前言
Java线程分为几种状态,在网上一搜,答案不尽人意。很多文章还写着有五种状态,这其实是在误导别人。要想知道线程分为几种状态,最正确的方式就是直接查看jdk源码。
查看源码
Thread 类内部有一个枚举类型 State,直接看代码:
public class Thread implements Runnable {
// 其他代码(忽略)
......
public enum State {
/**
* 尚未启动的线程的线程状态。
*/
NEW,
/**
* 可运行线程的线程状态。可运行的线程状态即正在
* Java虚拟机中执行,但它可能正在等待来自操作系统
* 的其他资源例如处理器。
*/
RUNNABLE,
/**
* 等待监视器锁定时被阻塞的线程的线程状态。
* 处于阻塞状态的线程正在等待监视器锁。
*/
BLOCKED,
/**
* 等待线程的线程状态。
* 由于调用了以下的方法:
* <ul>
* <li>{@link Object#wait() Object.wait} 没有设置超时时间</li>
* <li>{@link #join() Thread.join} 没有设置超时时间</li>
* <li>{@link LockSupport#park() LockSupport.park}</li>
* </ul>
*
* 处于等待状态的线程正在等待另一个线程执行特定的动作。
*
* 例如,一个线程调用 <tt>Object.wait()</tt>,那么这个对象就会处于
* 等待状态,直到另一个线程调用这个对象的 <tt>Object.notify()</tt>
* 或者 <tt>Object.notifyAll()</tt> 才能解除状态。
* 一个线程调用<tt>Thread.join()</tt>正在等待指定的线程终止。
*/
WAITING,
/**
* 具有指定等待时间的等待线程的线程状态。
* 由于调用具有指定等待时间的以下方法:
* <ul>
* <li>{@link #sleep Thread.sleep}</li>
* <li>{@link Object#wait(long) Object.wait} 设置了超时时间</li>
* <li>{@link #join(long) Thread.join} 设置了超时时间</li>
* <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
* <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
* </ul>
*/
TIMED_WAITING,
/**
* 终止线程的线程状态。
* 线程已完成执行。
*/
TERMINATED;
}
}
可以看到,Java中定义了线程有 6种状态,分别是:
- NEW(新建):创建线程对象后尚未启动的线程,即未调用start方法
- RUNNABLE(运行):Java线程中将就绪(ready)和运行中(running)两种状态笼统的称为“运行”。线程对象创建后,调用了该对象的start()方法,该状态的线程位于可运行线程池中,等待被线程调度选中,获取CPU的使用权,此时处于就绪状态(ready)。就绪状态的线程在获得CPU时间片后变为运行中状态(running)。
- BLOCKED(阻塞):当线程等待获取互斥锁时,会进入阻塞态
- WAITING(无限期等待):不会被分配CPU时间,需要显式被唤醒
- 没有设置 Timeout 参数的 Object.wait() 方法
- 没有设置 超时时间 参数的 Thread.join() 方法
- LockSupport.park() 方法
- 没有设置 Timeout 参数的 Object.wait() 方法
- TIMED_WAITING(限期等待):在一定时间后会由系统自动唤醒
- Thread.sleep() 方法
- 设置了 Timeout 参数的 Object.wait() 方法
- 设置了 超时时间 参数的 Thread.join() 方法
- LockSupport.parkNanos() 方法
- LockSupport.parkUntil() 方法
- Thread.sleep() 方法
- TERMINATED(终止):已终止线程的状态,线程已经结束执行