-
状态介绍
初始(NEW):新创建了一个线程对象,但还没有调用start()方法。运行(RUNNABLE):Java线程中将就绪(ready)和运行中(running)两种状态笼统的成为“运行”。线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取cpu 的使用权,此时处于就绪状态(ready)。就绪状态的线程在获得cpu 时间片后变为运行中状态(running)。阻塞(BLOCKED):线程阻塞于锁(不是JUC中的锁)。等待(WAITING):进入该状态的线程需要等待其他线程做出一些特定动作(通知或中断)。超时等待(TIME_WAITING):该状态不同于WAITING,它可以在指定的时间内自行返回。终止(TERMINATED):表示该线程已经执行完毕。 可以通过jstack pid命令来判断线程处于的状态,如下所示:
$ jstack 119122018-07-12 14:46:48Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.111-b14 mixed mode):"Attach Listener" #13 daemon prio=9 os_prio=31 tid=0x00007fbcd919a800 nid=0x3d07 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE"NettythreadDeathWatcher-2-1" #12 daemon prio=1 os_prio=31 tid=0x00007fbcd9198800 nid=0x4303 waiting on condition [0x0000700006a92000] java.lang.Thread.State: TIMED_WAITING (sleeping) at java.lang.Thread.sleep(Native Method) at io.netty.util.ThreadDeathWatcher$Watcher.run(ThreadDeathWatcher.java:152) at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:144) at java.lang.Thread.run(Thread.java:745)"DestroyJavaVM" #11 prio=5 os_prio=31 tid=0x00007fbcda010800 nid=0x2703 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE
- 状态查看 通过jps查看当前Java进程,然后通过jstack 进程id 可以查看到该进行下多个线程的状态(初始和终止两种状态无法查看),几个例子如下:
- 运行
new Thread(new Runnable() { @Override public void run() { //死循环,一直保持线程运行 for (;;){ } }},"runningStatusThread").start();//jstack结果"runningStatusThread" prio=6 tid=0x023c4400 nid=0xa19c runnable [0x04bcf000] java.lang.Thread.State: RUNNABLE at com.blackstar.concurrent.ThreadStatusTest$1.run(ThreadStatusTest.java:20) at java.lang.Thread.run(Thread.java:662)
- 等待
new Thread(new Runnable() { @Override public void run() { //暂停当前线程,等待许可 LockSupport.park(); }}, "waitingStatusThread").start();//jstack结果"waitingStatusThread" prio=6 tid=0x023e6c00 nid=0xaf98 waiting on condition [0x04cbf000] java.lang.Thread.State: WAITING (parking) at sun.misc.Unsafe.park(Native Method) at java.util.concurrent.locks.LockSupport.park(LockSupport.java:283) at com.blackstar.concurrent.ThreadStatusTest$1.run(ThreadStatusTest.java:21) at java.lang.Thread.run(Thread.java:662)
- 超时等待
new Thread(new Runnable() { @Override public void run() { //暂定当前线程2^63-1纳秒,然后释放 LockSupport.parkNanos(Long.MAX_VALUE); }},"timeWaitingStatusThread").start();//jstack结果"timeWaitingStatusThread" prio=6 tid=0x02426800 nid=0xadb4 waiting on condition [0x04c2f000] java.lang.Thread.State: TIMED_WAITING (parking) at sun.misc.Unsafe.park(Native Method) at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:317) at com.blackstar.concurrent.ThreadStatusTest$1.run(ThreadStatusTest.java:23) at java.lang.Thread.run(Thread.java:662)
- 阻塞
//借助一个对象,对象提供同步的block方法private static class BlockObj { public synchronized void block(){ //死循环 for(;;){ } }}
final BlockObj blockObj = new BlockObj();new Thread(new Runnable() { @Override public void run() { blockObj.block(); }},"useBlockObjThread").start();try { //main线程休眠一秒,让使用block的线程充分运行 Thread.sleep(1000);} catch (InterruptedException e) { e.printStackTrace();}new Thread(new Runnable() { @Override public void run() { blockObj.block(); }},"blockStatusThread").start();//jstack结果"blockStatusThread" #12 prio=5 os_prio=0 tid=0x00000000592fe800 nid=0x7554 waiting for monitor entry [0x000000005a4fe000] java.lang.Thread.State: BLOCKED (on object monitor) at com.blackstar.concurrent.ThreadStatusTest$BlockObj.block(ThreadStatusTest.java:21) - waiting to lock <0x00000000d700a748> (a com.blackstar.concurrent.ThreadStatusTest$BlockObj) at com.blackstar.concurrent.ThreadStatusTest$2.run(ThreadStatusTest.java:43) at java.lang.Thread.run(Thread.java:745)
- 运行
- 状态联系与区别
- 就绪与运行中 就绪与运行中两种状态在Java中都被称为运行状态,就绪状态表示该线程已经准备好,但还没有被CPU调度,运行状态则表示该线程已经在CPU中运行。
- 等待与超时等待 处于等待状态的线程需要其他线程对它做出一些操作后,它才能够继续进行,而处于超时等待的线程在过了指定时间后,会自动运行。
- 等待与阻塞 处于等待状态的线程需要其他线程将它唤醒或者打断,而阻塞的线程需要等待其他线程将资源释放,该线程才能继续运行,时间不可控制。从linux内核来看,这些线程的状态都是等待状态,没区别,区别只在于java的管理需要。
参考书籍及网址:
- 《Java并发编程的艺术》
- 《深入理解Java虚拟机》
- https://www.zhihu.com/question/27654579 Java线程中wait状态和block状态的区别?
PS:研究基于MAC+Idea+JDK1.8 64位
Keep Calm and Carry on!