51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

Thread 状态速查手册

前言 {#前言}

梳理早期与 Thread 状态相关的笔记。

状态分类 {#状态分类}

通过查看 Thread 源码,我们可以看到在其类内部定义了线程的状态枚举:

|------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------| | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | public class Thread implements Runnable { public enum State { NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED; } ... } |

Thread 线程大致分为 6 种,即 NEWRUNNABLEBLOCKEDWAITINGTIMED_WAITINGTERMINATED

其中:

  • NEW : 新建状态(尚未启动的线程状态),即刚 new 出来,还没执行 start() 方法。
  • RUNNABLE :可运行状态,可以细分两种 READY (就绪状态,调用了 start() 方法,等待获取 CPU 资源运行)和 RUNNING(运行状态,已获取到 CPU 资源)。
  • BLOCKED:阻塞状态,等待拿到监视器锁/对象锁进入到同步方法或同步代码块。
  • WAITING:等待状态
  • TIMED_WAITING:超时等待状态
  • TERMINATED:终止状态

状态转换 {#状态转换}

  • 当线程被new 出来时,处在 NEW 状态
  • NEW 状态的线程调用 start() 方法后会变成 READY 状态。
  • READY 状态的线程拿到 CPU 资源就可以执行任务,此时状态变为 RUNNING
  • RUNNING 状态中的线程会随着遇到不同情况,状态发生不同的变化:

  ① 线程成功执行完方法或中途遇到异常,状态会变为 TERMINATED

  ② 线程在进到同步方法或同步代码块前,如果没有获取到监视器锁/对象锁,那么状态就会变为 BLOCKED

  ③ 线程在运行过程中调用了 Object 的 wait()、Thread 的 join()、LockSupport.park() 方法后,状态会变成 WAITING

  ④ 线程在运行过程中调用了 Object 的 wait(time)、Thread 的 sleep(time)、LockSupport.parkNanos(time)、LockSupport.parkUntil(time) 方法后,状态会变成 TIMED_WAITING

  • 处在 BLOCKED 状态的线程会被放到同步队列 中。当持有锁的线程释放锁后会唤醒同步队列 的线程,此时同步队列 中的线程状态会变为 READY 竞争对象锁,如果竞争成功状态变为 RUNNING 。竞争失败则状态再次变回 BLOCKED ,被放回同步队列重复操作。
  • 处在 WAITING 状态的线程会被放到等待队列 中。当其他线程调用 notify()notifyAll()unpark(thread) 会唤醒等待队列 的线程,此时等待队列 中的线程状态会变为 READY 去竞争对象锁,如果竞争成功状态变为 RUNNING ,从 wait() 方法中返回。竞争失败则状态变成 BLOCKED ,被放进同步队列
  • 处在 TIMED_WAITING 状态的线程会被放到等待队列 中。有两种情况会唤醒等待队列 中的该状态的线程,一种是手动调用 notify()notifyAll()unpark(thread) 方法,另一种是等待时间过后由 JVM 会自动调用 notifyAll() 方法唤醒,然后执行上边描述的操作。

参考资料 {#参考资料}

赞(0)
未经允许不得转载:工具盒子 » Thread 状态速查手册