浅谈Java线程的生命周期

概述

在Java中线程的生命周期中共有6种不同的状态:

  • 初始状态(NEW):线程已经构建,尚未启动。 → 线程刚创建时的状态。
  • 运行状态(RUNNABLE):包括(可运行)就绪(READY)和运行中(RUNNING)两种状态,统称为运行状态。 → 线程创建后调用#start()方法即可进入该状态。
  • 阻塞状态(BLOCKED):线程被锁阻塞。
  • 等待状态(WAITING):线程需要等待其他线程做出特定动作(通知或中断)。
  • 超时等待状态(TIME_WAITING):不同于等待状态,超时等待状态可以在指定的时间自行返回。
  • 终止状态(TERMINATED):当前线程已经执行完毕。

在操作系统层面,Java 线程中的 BLOCKED、WAITING、TIMED_WAITING 是同一种状态,即休眠状态。也就是说只要 Java 线程处于这三种状态之一,那么这个线程就永远没有 CPU 的使用权。

状态转换图如下所示:
在这里插入图片描述

注意上面的图有个错误,wait到 runnable状态的转换中,join实际上是Thread类的方法,但这里写成了Object

RUNNABLE 与 BLOCKED 的状态转换

只有「线程等待 synchronized 的隐式锁」这种场景才会发生上述状态转换。当等待的线程获得 synchronized 隐式锁时,就又会从 BLOCKED 转换到 RUNNABLE 状态。

Q:线程调用阻塞式 API 时,是否会转换到 BLOCKED 状态呢?
A:在操作系统层面,线程是会转换到休眠状态的,但是在 JVM 层面,Java 线程的状态不会发生变化。因为在 JVM 看来,等待 CPU 使用权(操作系统层面此时处于可执行状态)与等待 I/O(操作系统层面此时处于休眠状态)没有区别,都是在等待某个资源,所以都归入了 RUNNABLE 状态。
而我们平时所谓的 Java 在调用阻塞式 API 时,线程会阻塞,指的是操作系统线程的状态,并不是 Java 线程的状态。

RUNNABLE 与 WAITING 的状态转换

  1. 获得 synchronized 隐式锁的线程,调用无参数的 Object.wait() 方法
  2. 调用无参数的 Thread.join() 方法。其中的 join() 是一种线程同步方法,例如有一个线程对象 thread A,当调用 A.join() 的时候,执行这条语句的线程会等待 thread A 执行完,而等待中的这个线程,其状态会从 RUNNABLE 转换到 WAITING。当线程 thread A 执行完,原来等待它的线程又会从 WAITING 状态转换到 RUNNABLE。
  3. 调用 LockSupport.park() 方法。→ JUC中的锁,都是基于它实现的。调用 LockSupport.park() 方法,当前线程会阻塞,线程的状态会从 RUNNABLE 转换到 WAITING。调用 LockSupport.unpark(Thread thread) 可唤醒目标线程,目标线程的状态又会从 WAITING 状态转换到 RUNNABLE。

RUNNABLE 与 TIMED_WAITING 的状态转换

  1. 调用带超时参数的 Thread.sleep(long millis) 方法
  2. 获得 synchronized 隐式锁的线程,调用带超时参数的 Object.wait(long timeout) 方法
  3. 调用带超时参数的 Thread.join(long millis) 方法
  4. 调用带超时参数的 LockSupport.parkNanos(Object blocker, long deadline) 方法
  5. 调用带超时参数的 LockSupport.parkUntil(long deadline) 方法。

RUNNABLE 与 TERMINATED 的状态转换

  1. 线程执行完 run() 方法后,会自动转换到 TERMINATED 状态。
  2. 如果执行 run() 方法的时候异常抛出,也会导致线程终止。
  3. 强制终止的方法:stop()、suspend()、resume() 已经过时 → 立即终止线程,被这些方法终止的线程并不会自动调用JUC包下锁的unlock()去释放锁,很容易造成死锁!(synchronized不会发生上述情况,因为他是JVM层面的,会自动释放)、interrupt() 方法(优雅关闭,推荐使用)。

参考:王宝令老师极客时间专栏《Java 并发编程实战》,质量很高,非常推荐!

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值