## 线程状态转换 ![](https://box.kancloud.cn/aa2738b665d6b3257a9066abb33266b8_960x541.png) ### 新建(New) 创建后尚未启动。 ### 可运行(Runnable) 可能正在运行,也可能正在等待 CPU 时间片。 包含了操作系统线程状态中的 运行(Running ) 和 就绪(Ready)。 ### 阻塞(Blocking) 这个状态下,是在多个线程有同步操作的场景,比如正在等待另一个线程的 synchronized 块的执行释放,或者可重入的 synchronized 块里别人调用 wait() 方法,也就是线程在等待进入临界区。 阻塞可以分为:等待阻塞,同步阻塞,其他阻塞 ### 无限期等待(Waiting) 等待其它线程显式地唤醒,否则不会被分配 CPU 时间片。 | 进入方法 | 退出方法 | | --- | --- | | 没有设置 Timeout 参数的 Object.wait() 方法 | Object.notify() / Object.notifyAll() | | 没有设置 Timeout 参数的 Thread.join() 方法 | 被调用的线程执行完毕 | | LockSupport.park() 方法 | \- | ### 限期等待(Timed Waiting) 无需等待其它线程显式地唤醒,在一定时间之后会被系统自动唤醒。 调用 Thread.sleep() 方法使线程进入限期等待状态时,常常用 “**使一个线程睡眠**” 进行描述。 调用 Object.wait() 方法使线程进入限期等待或者无限期等待时,常常用 “**挂起一个线程**” 进行描述。 **睡眠和挂起**是用来描述**行为**,而**阻塞**和等待用来描述**状态**。 阻塞和等待的区别在于,阻塞是被动的,它是在等待获取一个排它锁。而等待是主动的,通过调用 Thread.sleep() 和 Object.wait() 等方法进入。 | 进入方法 | 退出方法 | | --- | --- | | Thread.sleep() 方法 | 时间结束 | | 设置了 Timeout 参数的 Object.wait() 方法 | 时间结束 / Object.notify() / Object.notifyAll() | | 设置了 Timeout 参数的 Thread.join() 方法 | 时间结束 / 被调用的线程执行完毕 | | LockSupport.parkNanos() 方法 | \- | | LockSupport.parkUntil() 方法 | \- | ### 死亡(Terminated) * 线程因为 run 方法正常退出而自然死亡 * 因为一个没有捕获的异常终止了 run 方法而意外死亡