东莞网站设计精英,网站关键词优化排名怎么做,教育培训机构网站建设,互助盘网站怎么做的java线程状态#xff1a;
初始(NEW)#xff1a;新创建了一个线程对象#xff0c;但还没有调用start()方法。运行(RUNNABLE)#xff1a;Java线程中将就绪#xff08;ready#xff09;和运行中#xff08;running#xff09;两种状态笼统的称为“运行”。 线程对象创建…java线程状态
初始(NEW)新创建了一个线程对象但还没有调用start()方法。运行(RUNNABLE)Java线程中将就绪ready和运行中running两种状态笼统的称为“运行”。 线程对象创建后其他线程(比如main线程调用了该对象的start()方法。该状态的线程位于可运行线程池中等待被线程调度选中获取CPU的使用权此时处于就绪状态ready。就绪状态的线程在获得CPU时间片后变为运行中状态running。阻塞(BLOCKED)表示线程阻塞于锁。等待(WAITING)进入该状态的线程需要等待其他线程做出一些特定动作通知或中断。超时等待(TIMED_WAITING)该状态不同于WAITING它可以在指定的时间后自行返回。终止(TERMINATED)表示该线程已经执行完毕。
Java Monitor原理 Monitor 是Java中用以实现线程之间的互斥与协作的主要手段可以看成是对象或者Class的锁。每一个对象有且仅有一个monitor。Java 的 Object 类本身就是监视者对象Java 对于 Monitor Object 模式做了内建的支持。 Object 类本身就是监视者对象 每个 Object 都带了一把看不见的锁通常叫 内部锁/Monitor 锁/Instrinsic Lock, 这把锁就是 监控锁。 synchronized 关键字修饰方法和代码块就是 同步方法 wait()/notify()/notifyAll() 方法构成监控条件(Monitor Condition) 线程和Monitor之间关系 一个Monitor在某个时刻只能被一个线程拥有该线程就是Active Thread 而其它线程都是Waiting Thread分别在两个队列Entry Set和Wait Set里面等候。 在Entry Set中等待的线程状态是Waiting for monitor entry 在Wait Set中等待的线程状态是in Object.wait()。
线程进入同步方法中 为了继续执行临界区代码线程必须获取 Monitor 锁。如果获取锁成功将成为该监视者对象的拥有者。任一时刻内监视者对象只属于一个活动线程The Owner 拥有监视者对象的线程可以调用 wait() 进入等待集合Wait Set同时释放监视锁进入等待状态。 其他线程调用 notify() / notifyAll() 接口唤醒等待集合中的线程这些等待的线程需要重新获取监视锁后才能执行 wait() 之后的代码。 同步方法执行完毕了线程退出临界区并释放监视锁。
进入区(Entrt Set):表示线程通过synchronized要求获取对象的锁。如果对象未被锁住,则迚入拥有者;否则则在进入区等待。一旦对象锁被其他线程释放,立即参与竞争。 拥有者(The Owner):表示某一线程成功竞争到对象锁。 等待区(Wait Set):表示线程通过对象的wait方法,释放对象的锁,并在等待区等待被唤醒。
线程调用修饰 表示线程在方法调用时,额外的重要的操作一般出现在线程内容中用来协助分析线程的状态。 locked 对象地址 对象名 表示当前线程通过synchronized关键字成功获取到了目标对象的监视器拥有了在临界区操作的权限状态一般为runnable。注意对象锁是可重入的所以这里有2次锁住了同一个对象。 waiting to lock 对象地址 对象名 表示当前线程未能通过synchronized关键字获取到目标对象的监视器状态一般为blocked。 waiting on对象地址 对象名 表示当前线程通过synchronized关键字成功获取到了目标对象的监视器但调用了wait方法,进入对象的等待区等待。在调用栈顶出现,线程状态为WAITING或TIMED_WATING。 parking to wait for 对象地址 对象名 park是基本的线程阻塞原语,不通过监视器在对象上阻塞。随concurrent包会出现的新的机制,与synchronized体系不同具体介绍可以看stackoverflow上的回答传送门。
系统线程状态 出现在线程信息第一行的末尾。 deadlock死锁线程 runnable表示线程运行中或I/O等待线程状态一般为RUNNABLE。 in Object.wait()进入临界区之后又调用了java.lang.Object.wait()方法等待,jvm线程状态一般为WAITING或TIMED_WAITING。 waiting for monitor entry在等待进入一个临界区,线程状态一般状态为BLOCKED。 waiting on condition线程正处于等待资源或等待某个条件的发生具体的原因需要结合下面堆栈信息进行分析。 1如果堆栈信息明确是应用代码则证明该线程正在等待资源一般是大量读取某种资源且该资源采用了资源锁的情况下线程进入等待状态等待资源的读取或者正在等待其他线程的执行等。 2如果发现有大量的线程都正处于这种状态并且堆栈信息中得知正等待网络读写这是可能因为网络阻塞导致线程无法执行。 3还有一种常见的情况是该线程在sleep等待sleep的时间到了将被唤醒。
JVM线程状态 java.lang.Thread.State: RUNNABLE 线程运行中或I/O等待 方法调用-无 java.lang.Thread.State: BLOCKED (on object monitor) 等待进入一个临界区 方法调用-synchronized java.lang.Thread.State: TIMED_WAITING (parking) 线程等待唤醒并且设置等待时长 方法调用-LockSupport.parkNanos(等待时长)、LockSupport.parkUntil(等待时长) java.lang.Thread.State: TIMED_WAITING (sleeping) 线程等待唤醒并且设置等待时长 方法调用-Thread.sleep(等待时长)Thread.join(等待时长) java.lang.Thread.State: TIMED_WAITING (on object monitor) 线程在等待唤醒并且设置等待时长 方法调用-Object.wait(等待时长) java.lang.Thread.State: WAITING (parking) 线程等待唤醒没有设置等待时长 方法调用-LockSupport.park() java.lang.Thread.State: WAITING (on object monitor) 线程等待唤醒并且没有设置等待时长 方法调用-Object.wait() java.lang.Thread.State: WAITING (on object monitor) 线程等待唤醒没有设置等待时长 方法调用-Thread.join()
jvm日志分析 “ForkJoinPool.commonPool-worker-52”{线程名} #5688{线程ID} daemon prio5{线程的优先级取值范围为[1-10]默认为 5数值越低越有优先} os_prio0{线程在操作系统中的优先级} tid0x00007f31eb3f3800 nid0xa8ec{Native thread ID本地操作系统相关的线程id,对应JVM 虚拟机中线程映射在操作系统中的线程编号。这个nid就是我们用top -Hp pid 查看到的线程号不过要用printf %x\n转换一下进制} waiting on condition [0x00007f31944d0000]{系统线程状态} java.lang.Thread.State: WAITING (parking){JVM线程状态} at sun.misc.Unsafe.park(Native Method) - parking to wait for 0x00000004706e6598 (a java.util.concurrent.ForkJoinPool) at java.util.concurrent.ForkJoinPool.awaitWork(ForkJoinPool.java:1824) at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1693) at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
Locked ownable synchronizers: - None
常见问题 1锁争用 如果出现大量的锁争用可能是线程阻塞了 #48线程获得了 0x000000046b9b6078对象的锁进入了临界区#49无法获取到锁停留在Entry Set中输出waiting to lock 0x000000046b9b6078。 “hiveserver2-web-49-acceptor-223302924-ServerConnector6d6d480c{HTTP/1.1,[http/1.1]}{0.0.0.0:10002}” #49 daemon prio3 os_prio0 tid0x00007f31eaf33000 nid0x6306 waiting for monitor entry [0x00007f31a3dfc000] java.lang.Thread.State: BLOCKED (on object monitor) --JVM线程状态 at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:234) - waiting to lock 0x000000046b9b6078 (a java.lang.Object) at org.eclipse.jetty.server.ServerConnector.accept(ServerConnector.java:397) at org.eclipse.jetty.server.AbstractConnector$Acceptor.run(AbstractConnector.java:601) at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:671) at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:589) at java.lang.Thread.run(Thread.java:748)
Locked ownable synchronizers: - None “hiveserver2-web-48-acceptor-1580fe4f0-ServerConnector6d6d480c{HTTP/1.1,[http/1.1]}{0.0.0.0:10002}” #48 daemon prio3 os_prio0 tid0x00007f31eaf31800 nid0x6305 runnable [0x00007f31a3efd000] java.lang.Thread.State: RUNNABLE at sun.nio.ch.ServerSocketChannelImpl.accept0(Native Method) at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:422) at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:250) - locked 0x000000046b9b6078 (a java.lang.Object) at org.eclipse.jetty.server.ServerConnector.accept(ServerConnector.java:397) at org.eclipse.jetty.server.AbstractConnector$Acceptor.run(AbstractConnector.java:601) at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:671) at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:589) at java.lang.Thread.run(Thread.java:748)
Locked ownable synchronizers: - None
2死锁 如果两个线程相互都被对方的线程锁锁住这样就造成了死锁。 Thread1获取了0x00000000d8251168锁等待0x00000000d8251198锁Thread2获取了0x00000000d8251198锁等待0x00000000d8251168锁。导致死锁 “Thread2” daemon prio5 tid0x00007f1d3825f800 nid0x2142 waiting for monitor entry [0x00007f1d16eeb000] java.lang.Thread.State: BLOCKED (on object monitor) at com.jvm.study.threaddump.deadlock.DeadLockMock$2.run(DeadLockMock.java:31) - waiting to lock 0x00000000d8251168 (a java.lang.String) - locked 0x00000000d8251198 (a java.lang.String) “Thread1” daemon prio5 tid0x00007f1d3825e000 nid0x2141 waiting for monitor entry [0x00007f1d16fec000] ava.lang.Thread.State: BLOCKED (on object monitor) at com.jvm.study.threaddump.deadlock.DeadLockMock$1.run(DeadLockMock.java:16) - waiting to lock 0x00000000d8251198 (a java.lang.String) - locked 0x00000000d8251168 (a java.lang.String)
3等待区等待 JVM线程的状态是java.lang.Thread.State: TIMED_WAITING (on object monitor)线程调用了java.lang.Object.wait(Native Method)方法而进入了等待状态。 Wait Set中等待的线程状态就是 in Object.wait() 当线程获得了Monitor进入临界区之后如果发现线程继续运行的条件没有满足它就调用对象通常是被synchronized的对象的wait()方法放弃了Monitor进入Wait Set队列中。 只有当别的线程在该对象上调用了notify()或notifyAll()方法 “Wait Set” 队列中线程才得到机会去竞争但是只有一个线程获得对象的 Monitor从而恢复到运行态。 “IPC Client (2108708444) connection to IT-CDH-Node02/10.11.16.36:8020 from hive” #5681 daemon prio5 os_prio0 tid0x00007f31ccf4a000 nid0xa8e4 in Object.wait() [0x00007f319aa33000] java.lang.Thread.State: TIMED_WAITING (on object monitor) at java.lang.Object.wait(Native Method) at org.apache.hadoop.ipc.ClientConnection.waitForWork(Client.java:1017) - locked 0x000000042b52dbf0 (a org.apache.hadoop.ipc.Client$Connection) at org.apache.hadoop.ipc.ClientConnection.run(Client.java:1061)
Locked ownable synchronizers: - None