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:
     * 
    *
  • {@link #NEW}
    * A thread that has not yet started is in this state. *
  • *
  • {@link #RUNNABLE}
    * A thread executing in the Java virtual machine is in this state. *
  • *
  • {@link #BLOCKED}
    * A thread that is blocked waiting for a monitor lock * is in this state. *
  • *
  • {@link #WAITING}
    * A thread that is waiting indefinitely for another thread to * perform a particular action is in this state. *
  • *
  • {@link #TIMED_WAITING}
    * A thread that is waiting for another thread to perform an action * for up to a specified waiting time is in this state. *
  • *
  • {@link #TERMINATED}
    * A thread that has exited is in this state. *
  • *
* *

* 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: *

    *
  • {@link Object#wait() Object.wait} with no timeout
  • *
  • {@link #join() Thread.join} with no timeout
  • *
  • {@link LockSupport#park() LockSupport.park}
  • *
* *

A thread in the waiting state is waiting for another thread to * perform a particular action. * * For example, a thread that has called Object.wait() * on an object is waiting for another thread to call * Object.notify() or Object.notifyAll() on * that object. A thread that has called Thread.join() * 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: *

    *
  • {@link #sleep Thread.sleep}
  • *
  • {@link Object#wait(long) Object.wait} with timeout
  • *
  • {@link #join(long) Thread.join} with timeout
  • *
  • {@link LockSupport#parkNanos LockSupport.parkNanos}
  • *
  • {@link LockSupport#parkUntil LockSupport.parkUntil}
  • *
*/
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并发编程的艺术》一书中,对线程的状态迁移做了很好的总结,这里直接引用书中的图片,并感谢方腾飞等老师。
Java线程状态详解_第1张图片

四. 注意事项

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

你可能感兴趣的:(Java并发编程)