目录前言Java 线程状态状态转换其它前言最近看到一篇 cnblog 上的文章《Java中一个线程只有六个状态》有些感悟便记录下来用做以后学习和工作中参考与考证。Java 线程状态首先归纳一下这篇文章中的重点即 Java 线程到底有几种状态分别哪几种打开 JDK Thread 类的源码不难找到在 Thread 类内部定义了一个 State 枚举类publicenumState{/** * Thread state for a thread which has not yet started. */NEW,/** * Thread state for a runnable thread. A thread in the runnable * state is executing in the Java virtual machine but it may * be waiting for other resources from the operating system * such as processor. */RUNNABLE,/** * Thread state for a thread blocked waiting for a monitor lock. * A thread in the blocked state is waiting for a monitor lock * to enter a synchronized block/method or * reenter a synchronized block/method after calling * {link Object#wait() Object.wait}. */BLOCKED,/** * Thread state for a waiting thread. * A thread is in the waiting state due to calling one of the * following methods: * ul * li{link Object#wait() Object.wait} with no timeout/li * li{link #join() Thread.join} with no timeout/li * li{link LockSupport#park() LockSupport.park}/li * /ul * * pA thread in the waiting state is waiting for another thread to * perform a particular action. * * For example, a thread that has called ttObject.wait()/tt * on an object is waiting for another thread to call * ttObject.notify()/tt or ttObject.notifyAll()/tt on * that object. A thread that has called ttThread.join()/tt * is waiting for a specified thread to terminate. */WAITING,/** * Thread state for a waiting thread with a specified waiting time. * A thread is in the timed waiting state due to calling one of * the following methods with a specified positive waiting time: * ul * li{link #sleep Thread.sleep}/li * li{link Object#wait(long) Object.wait} with timeout/li * li{link #join(long) Thread.join} with timeout/li * li{link LockSupport#parkNanos LockSupport.parkNanos}/li * li{link LockSupport#parkUntil LockSupport.parkUntil}/li * /ul */TIMED_WAITING,/** * Thread state for a terminated thread. * The thread has completed execution. */TERMINATED;}正如该作者所言共有6个值NEW、RUNNABLE、BLOCKED、TIMED_WAITING、WAITING、TERMINATED。这里我故意去掉这几个状态的中文翻译因为我觉得记住这几个英文单词有时比记住其翻译对于理解其背后含义更有助益且不会产生混淆。状态转换根据 State 枚举类的注释和该作者的解释分别对以下几种状态进行阐述NEW线程创建之后尚未启动之前RUNNABLE线程正在 Java 虚拟机中运行但也可能是在等待操作系统分配资源比如处理器BLOCKED线程处于等待获取 monitor 锁的状态。处于当前状态的线程要么是在等待锁从而进入同步代码块/同步方法要么是调用 wait() 方法后重新进入同步代码块/同步方法WAITING/TIMED_WAITING如果一个线程处于该状态是因为调用了 Object.wait、Thread.join、LockSupport.park。注意wait 方法会释放对象锁而 join 不会。TERMINATED当线程正常执行完成后。另外sleep、I/O交互、join 时都不会释放对象锁只有待 join 线程或 sleep 或 I/O操作结束后线程才会继续执行貌似处于一 种阻塞的状态。但实际上并没有“阻塞”这种状态阻塞只是线程运行过程中的一种现象线程本身仍处于之前的 WAITING、TIMED_WAITING或RUNNABLE 状态。还有一种情况是调用 suspend 方法不过该方法及其配套方法 resume 均已弃用不过多介绍。综上可以绘制出一张状态之间的转换图其它除了以上状态和状态之间的转换还流行其它一些说法比如阻塞、可运行等状态但这些只是为了方便大家理解其并未在 JDK 中有定义所以如果这些说法对你理解线程有益则可以利用如果适得其反还是不要掺杂进来的好。还有就是线程状态在运行期间尤其是在高负载系统中会频繁变化getState() 方法是最后一次观察到的状态不一定是实时的。如果需要精准监控线程状态可以使用 Lock 和 Condition 等工具来控制线程状态变化。并且在实际应用中并不需要频繁检查线程状态否则可能会引入不必要的复杂性相反可通过良好的同步机制如使用 wait() 和 notify()来控制线程的行为和状态。