Java线程状态详解

时间:2022-07-24
本文章向大家介绍Java线程状态详解,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

Java线程状态详解

一. 背景

最近在深入研究Java并发编程,看到网上有很多关于线程状态的总结,有的不全面,有的根本就是错的。因此,在这里我结合最权威的Java源代码,尝试对Java线程状态进行一个详细的解读。

二. 线程状态定义

Java线程状态使用Thread的内部类State来表示,而在Thread类中,也有一个threadStatus字段来标明当前线程的状态。Java通过一个native方法将threadStatus的值映射成State枚举。废话不说,直接贴源码:

/**
     * A thread state.  A thread can be in one of the following states:
     * <ul>
     * <li>{@link #NEW}<br>
     *     A thread that has not yet started is in this state.
     *     </li>
     * <li>{@link #RUNNABLE}<br>
     *     A thread executing in the Java virtual machine is in this state.
     *     </li>
     * <li>{@link #BLOCKED}<br>
     *     A thread that is blocked waiting for a monitor lock
     *     is in this state.
     *     </li>
     * <li>{@link #WAITING}<br>
     *     A thread that is waiting indefinitely for another thread to
     *     perform a particular action is in this state.
     *     </li>
     * <li>{@link #TIMED_WAITING}<br>
     *     A thread that is waiting for another thread to perform an action
     *     for up to a specified waiting time is in this state.
     *     </li>
     * <li>{@link #TERMINATED}<br>
     *     A thread that has exited is in this state.
     *     </li>
     * </ul>
     *
     * <p>
     * A thread can be in only one state at a given point in time.
     * These states are virtual machine states which do not reflect
     * any operating system thread states.
     *
     * @since   1.5
     * @see #getState
     */
public enum State {
    /**
         * 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>
         *
         * <p>A thread in the waiting state is waiting for another thread to
         * perform a particular action.
         *
         * For example, a thread that has called <tt>Object.wait()</tt>
         * on an object is waiting for another thread to call
         * <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on
         * that object. A thread that has called <tt>Thread.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;
}

根据源码可以看出,Java的Thread有如下的几种状态:

  1. NEW:新建状态,表示一个Thread刚刚被创建出来,还没有启动
  2. RUNNABLE:可运行状态,表示线程处于可运行的就绪状态。一个新创建好的线程,调用其start()方法后,就会由NEW状态迁移到RUNNABLE状态。需要注意的是:这里的RUNNABLE是相对于JVM的状态来说的,而线程具体何时运行,取决于操作系统底层的资源调度。
  3. BLOCKED:阻塞状态,表示线程正在等待一个监视器锁(monitor lock),而监视器锁在Java代码中的体现就是synchronized关键字。也就是说:只有线程在等待进入synchronized修饰的代码块或方法时,线程才处于BLOCKED状态。
  4. WAITING:等待状态,表示线程在等待某些条件的到达。在调用以下方法后,线程会进入WAITING状态:
    1. Object中定义的无超时的wait()方法,等待一个同步监视器的唤醒;
    2. Thread中定义的无超时的join()方法,等待其他线程执行完毕;
    3. LockSupport.park()方法。
  5. TIMED_WAITING:超时等待状态,与WAITING状态类似,并在其基础上,增加了超时的限制。在调用以下方法后,线程会进入TIMED_WAITING状态:
    1. Thread.sleep()方法,线程定时休眠;
    2. Object中定义的带超时的wait()方法;
    3. Thread中定义的带超时的join()方法;
    4. LockSupport.parkNanos()方法;
    5. LockSupport.parkUntil()方法。
  6. TIMED_WAITING:终止状态,包括线程正常执行完毕和异常终止。

三. 线程状态迁移

在著名的《Java并发编程的艺术》一书中,对线程的状态迁移做了很好的总结,这里直接引用书中的图片,并感谢方腾飞等老师。

四. 注意事项

  1. 线程只有在等待进入synchronized代码块或方法时,才会进入BLOCKED状态。而对于Lock接口下的常用锁来说,由于底层都是调用了LockSupport中的方法,因此等待锁都是进入了WAITING或TIMED_WAITING状态(取决于是否定义了超时)。
  2. 对于yield()方法来说,其语义是指当前线程愿意让出CPU执行权,让CPU重新进行资源调度,但是并不会改变当前线程的状态。