当前位置: 首页 > news >正文

线程的生命周期

在 Java 中,线程的生命周期包含6 种状态,这些状态定义在Thread.State枚举中,状态之间会根据操作发生转换。理解线程状态转换是掌握多线程编程的基础。

一、线程的 6 种状态

根据 Java 官方文档,线程的状态分为以下 6 种:

状态名称说明
NEW(新建)线程对象已创建,但未调用start()方法(尚未启动)。
RUNNABLE(可运行)线程已启动,正在 JVM 中运行,或等待 CPU 调度(包含传统 OS 中的 “运行” 和 “就绪” 状态)。
BLOCKED(阻塞)线程等待获取 synchronized 锁(因竞争锁而被阻塞)。
WAITING(无限等待)线程无限期等待其他线程的特定操作(如notify()),无超时时间。
TIMED_WAITING(计时等待)线程等待指定时间后自动唤醒(如sleep(1000)wait(1000))。
TERMINATED(终止)线程执行完毕(run()方法结束)或因异常终止。

二、状态转换流程图

[NEW] ↓ (调用start())
[RUNNABLE] ↓ (获取锁失败)              ↓ (释放锁后重新竞争)
[BLOCKED] --------------------→ [RUNNABLE]↑                            ↓ (调用wait()/join()等)|                        [WAITING]|                            ↓ (被notify()/中断)|                            → [RUNNABLE]|                            ↓ (调用wait(超时)/sleep(超时)等)|                        [TIMED_WAITING]|                            ↓ (超时/被notify()/中断)└----------------------------→ [RUNNABLE]↓ (run()执行完毕/异常)[TERMINATED]

三、详细转换说明

1. NEW → RUNNABLE
  • 触发条件:调用线程对象的start()方法(不能重复调用,否则抛IllegalThreadStateException)。
  • 示例:
    Thread thread = new Thread(() -> {});
    System.out.println(thread.getState()); // 输出:NEW
    thread.start();
    System.out.println(thread.getState()); // 可能输出:RUNNABLE(取决于调度)
    
2. RUNNABLE ↔ BLOCKED
  • RUNNABLE → BLOCKED:线程尝试获取synchronized锁时,若锁被其他线程持有,则进入BLOCKED状态。
  • BLOCKED → RUNNABLE:持有锁的线程释放锁后,当前线程竞争到锁,重新进入RUNNABLE
  • 示例:
    Object lock = new Object();// 线程1先获取锁
    Thread t1 = new Thread(() -> {synchronized (lock) {try { Thread.sleep(1000); } // 持有锁休眠catch (InterruptedException e) {}}
    });// 线程2后尝试获取锁,会进入BLOCKED
    Thread t2 = new Thread(() -> {synchronized (lock) { // 此时t1持有锁,t2进入BLOCKEDSystem.out.println("获取锁成功");}
    });t1.start();
    Thread.sleep(100); // 确保t1先执行
    t2.start();
    System.out.println(t2.getState()); // 输出:BLOCKED
    
3. RUNNABLE ↔ WAITING
  • RUNNABLE → WAITING

    • 调用object.wait()(必须在synchronized块中,释放锁并等待)。
    • 调用thread.join()(等待目标线程执行完毕)。
    • 调用LockSupport.park()(无参数版本,阻塞当前线程)。
  • WAITING → RUNNABLE

    • 其他线程调用object.notify()object.notifyAll()(唤醒后需重新竞争锁)。
    • join()的目标线程执行完毕。
    • 其他线程调用LockSupport.unpark(thread)
  • 示例(wait()/notify()):

    Object lock = new Object();
    Thread t = new Thread(() -> {synchronized (lock) {try {lock.wait(); // 释放锁,进入WAITING} catch (InterruptedException e) {}}
    });
    t.start();
    Thread.sleep(100);
    System.out.println(t.getState()); // 输出:WAITING// 其他线程唤醒
    new Thread(() -> {synchronized (lock) {lock.notify(); // 唤醒t线程}
    }).start();
    
4. RUNNABLE ↔ TIMED_WAITING
  • RUNNABLE → TIMED_WAITING

    • 调用Thread.sleep(long millis)(不释放锁,仅暂停执行)。
    • 调用object.wait(long timeout)(释放锁,等待指定时间)。
    • 调用thread.join(long millis)(限时等待目标线程)。
    • 调用LockSupport.parkNanos()LockSupport.parkUntil()(限时阻塞)。
  • TIMED_WAITING → RUNNABLE

    • 等待时间超时。
    • 其他线程调用notify()/notifyAll()(需重新竞争锁)。
    • 线程被中断(interrupt())。
  • 示例(sleep()):

    Thread t = new Thread(() -> {try {Thread.sleep(1000); // 进入TIMED_WAITING} catch (InterruptedException e) {}
    });
    t.start();
    Thread.sleep(100);
    System.out.println(t.getState()); // 输出:TIMED_WAITING
    
5. RUNNABLE → TERMINATED
  • 触发条件
    • 线程的run()方法正常执行完毕。
    • 线程执行中抛出未捕获的异常(导致run()方法终止)。
  • 示例:
    Thread t = new Thread(() -> {});
    t.start();
    Thread.sleep(100); // 等待线程执行完毕
    System.out.println(t.getState()); // 输出:TERMINATED
    

四、关键注意点

  1. RUNNABLE的特殊含义:Java 中的RUNNABLE包含两种情况:

    • 线程正在 CPU 上执行(运行中)。
    • 线程就绪,等待 CPU 调度(未运行但可立即执行)。这与操作系统层面的 “运行” 和 “就绪” 状态不同,是 Java 对线程状态的简化抽象。
  2. BLOCKEDWAITING的区别

    • BLOCKED:等待synchronized 锁(被动等待,无需主动唤醒)。
    • WAITING:等待其他线程的特定操作(如notify(),需主动唤醒)。
  3. 状态不可逆:线程进入TERMINATED后,无法再回到其他状态(即使调用start()也会报错)。

  4. sleep()wait()的状态差异

    • sleep():线程进入TIMED_WAITING不释放锁
    • wait():线程进入WAITINGTIMED_WAITING释放锁

总结

线程的生命周期是多线程调度的核心,6 种状态的转换反映了线程从创建到终止的完整过程:

  • NEW启动到RUNNABLE,再根据锁竞争、等待操作进入BLOCKED/WAITING/TIMED_WAITING,最终执行完毕进入TERMINATED

理解这些状态转换,有助于诊断线程死锁、阻塞等问题,写出更可靠的多线程程序。

http://www.dtcms.com/a/415613.html

相关文章:

  • 网站建设男装定位微信公众平台注册官网入口
  • 廊坊seo网站排名ui设计培训班有用吗
  • 公司网站定位建议广州手工活外发加工网
  • 高光谱成像在壁画研究分析以及保护的应用
  • 从试水到普及,AI 通识课全面爆发
  • TCP/IP 的韧性:尽力而为 可靠传输协议
  • 与做网站的人怎么谈判网页设计与制作的原则
  • 咸宁网站建设价格有没有专做于投融资的网站
  • 门户网站建设和运行招标公告如何在第三方网站做推广
  • 南宁网站建设找哪家wordpress 技术类主题
  • 如何使用Python压缩和解压文件
  • 小迪web自用笔记40
  • 奇异值分解(Singular Value Decomposition, SVD)详解——从特征值到奇异值
  • 免费网站安全检测网络游戏名字大全
  • [冀信2025]雄
  • 住建部城乡建设网站中国核工业第二二建设有限公司地址
  • 卓手机建网站查询网站旗下域名
  • DevEco Studio 预览器的使用
  • jar包Tls检验问题处理
  • 网站总体设计方案优秀企业网站的特点
  • PyTorch 实现 CIFAR10 图像分类知识点总结
  • 商城维护工作内容网站建设wordpress 插件站
  • 做网站要的图片斗鱼刚做淘客没有网站
  • vite项目 查看代码编译过程的插件vite-plugin-inspect
  • C语言指针的概念
  • 做购物比价的网站有哪些做图片赚钱的网站
  • 一定要建设好网站才能备案吗中铁建设集团官网登录
  • 免备案自助建站网站天元建设集团有限公司企业号
  • inet_ntoa 函数深度解析
  • 四川省城乡建设厅官方网站附近模板木方市场