你该不会还不知道Java线程的几种状态吧?

340 阅读2分钟

前言

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() 方法
  • TIMED_WAITING(限期等待):在一定时间后会由系统自动唤醒
    • Thread.sleep() 方法
    • 设置了 Timeout 参数的 Object.wait() 方法
    • 设置了 超时时间 参数的 Thread.join() 方法
    • LockSupport.parkNanos() 方法
    • LockSupport.parkUntil() 方法
  • TERMINATED(终止):已终止线程的状态,线程已经结束执行

线程状态转换图