Spring & JVM

Java 世界中的线程到底有几种状态

Java 世界中的线程到底有几种状态

有说 5 种的,有说 6 种的,还有说 9 种的,各执一词,究竟谁对谁错?

源码分析

让我们从 OpenJDK 源码入手,抽丝剥茧,层层深入,揭开线程状态的神秘面纱。

JDK 源码

在 java.lang.Thread 包下可以看到使用了枚举类型 State 来定义了 6 种线程状态:

  • NEW
  • RUNNABLE
  • BLOCKED
  • WAITING
  • TIMED_WAITING
  • TERMINATED
/**
 * 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;
}

所以 6 种就是正确答案吗?不急着下结论,接着看!

HotSpot 源码

在头文件 javaClasses.hpp 中使用了枚举类型 ThreadStatus 来定义了 9 种线程状态:

  • NEW
  • RUNNABLE
  • SLEEPING
  • IN_OBJECT_WAIT
  • IN_OBJECT_WAIT_TIMED
  • PARKED
  • PARKED_TIMED
  • BLOCKED_ON_MONITOR_ENTER
  • TERMINATED
// Java Thread Status for JVMTI and M&M use.
// This thread status info is saved in threadStatus field of
// java.lang.Thread java class.
enum ThreadStatus {
  NEW                      = 0,
  RUNNABLE                 = JVMTI_THREAD_STATE_ALIVE +          // runnable / running
                             JVMTI_THREAD_STATE_RUNNABLE,
  SLEEPING                 = JVMTI_THREAD_STATE_ALIVE +          // Thread.sleep()
                             JVMTI_THREAD_STATE_WAITING +
                             JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT +
                             JVMTI_THREAD_STATE_SLEEPING,
  IN_OBJECT_WAIT           = JVMTI_THREAD_STATE_ALIVE +          // Object.wait()
                             JVMTI_THREAD_STATE_WAITING +
                             JVMTI_THREAD_STATE_WAITING_INDEFINITELY +
                             JVMTI_THREAD_STATE_IN_OBJECT_WAIT,
  IN_OBJECT_WAIT_TIMED     = JVMTI_THREAD_STATE_ALIVE +          // Object.wait(long)
                             JVMTI_THREAD_STATE_WAITING +
                             JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT +
                             JVMTI_THREAD_STATE_IN_OBJECT_WAIT,
  PARKED                   = JVMTI_THREAD_STATE_ALIVE +          // LockSupport.park()
                             JVMTI_THREAD_STATE_WAITING +
                             JVMTI_THREAD_STATE_WAITING_INDEFINITELY +
                             JVMTI_THREAD_STATE_PARKED,
  PARKED_TIMED             = JVMTI_THREAD_STATE_ALIVE +          // LockSupport.park(long)
                             JVMTI_THREAD_STATE_WAITING +
                             JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT +
                             JVMTI_THREAD_STATE_PARKED,
  BLOCKED_ON_MONITOR_ENTER = JVMTI_THREAD_STATE_ALIVE +          // (re-)entering a synchronization block
                             JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER,
  TERMINATED               = JVMTI_THREAD_STATE_TERMINATED
};

附:源码地址

那 9 种就是正确答案……吗?等等,接着看!

在 sun.jvm.hotspot.jdi 包下可以看到使用了接口类型 JVMTIThreadState 来定义了 13 种线程状态:

  • JVMTI_THREAD_STATE_ALIVE
  • JVMTI_THREAD_STATE_TERMINATED
  • JVMTI_THREAD_STATE_RUNNABLE
  • JVMTI_THREAD_STATE_WAITING
  • JVMTI_THREAD_STATE_WAITING_INDEFINITELY
  • JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT
  • JVMTI_THREAD_STATE_SLEEPING
  • JVMTI_THREAD_STATE_IN_OBJECT_WAIT
  • JVMTI_THREAD_STATE_PARKED
  • JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER
  • JVMTI_THREAD_STATE_SUSPENDED
  • JVMTI_THREAD_STATE_INTERRUPTED
  • JVMTI_THREAD_STATE_IN_NATIVE
// from JVMTI specification - refer to jvmti.xml
public interface JVMTIThreadState {
    public static final int JVMTI_THREAD_STATE_ALIVE = 0x0001;
    public static final int JVMTI_THREAD_STATE_TERMINATED = 0x0002;
    public static final int JVMTI_THREAD_STATE_RUNNABLE = 0x0004;
    public static final int JVMTI_THREAD_STATE_WAITING = 0x0080;
    public static final int JVMTI_THREAD_STATE_WAITING_INDEFINITELY = 0x0010;
    public static final int JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT = 0x0020;
    public static final int JVMTI_THREAD_STATE_SLEEPING = 0x0040;
    public static final int JVMTI_THREAD_STATE_IN_OBJECT_WAIT = 0x0100;
    public static final int JVMTI_THREAD_STATE_PARKED = 0x0200;
    public static final int JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER = 0x0400;
    public static final int JVMTI_THREAD_STATE_SUSPENDED = 0x100000;
    public static final int JVMTI_THREAD_STATE_INTERRUPTED = 0x200000;
    public static final int JVMTI_THREAD_STATE_IN_NATIVE = 0x400000;
}

附:源码地址

emmm……那应该是 13 种(小声)?

留言

您的电子邮箱地址不会被公开。