news 2026/6/15 6:44:13

一文搞懂线程状态转换与 Java 内存模型(内含通俗解释)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
一文搞懂线程状态转换与 Java 内存模型(内含通俗解释)

以下是一篇尽量通俗、结构清晰的文章,帮助你真正搞懂:

Java 线程的 6 种状态 + 状态转换图
以及 Java 内存模型(JMM)最核心的几件事

一、线程的 6 种状态(Java Thread.State 枚举)

Java 线程在 JVM 层面一共有这 6 种状态:

状态(英文)中文名称是否占用 CPU是否持有锁通俗解释
NEW新建刚 new Thread() 出来,还没调用 start(),相当于一张还没发出去的简历
RUNNABLE可运行是(有可能)可能线程正在 JVM 里“活着”,要么正在 CPU 上跑,要么在就绪队列排队等 CPU
BLOCKED阻塞(锁等待)想进 synchronized 代码块,但锁被别人拿着,像在银行排队等叫号
WAITING无限等待调用了 wait()、join()、LockSupport.park() 后进入,像睡着了等别人叫醒
TIMED_WAITING限时等待带时间的 wait(long)、sleep(long)、join(long)、parkNanos/parkUntil
TERMINATED终止run() 方法执行完毕(正常结束或异常抛出未捕获),线程彻底死亡

最容易混淆的三个状态对比

状态对比BLOCKEDWAITINGTIMED_WAITING
等待什么等待 monitor 锁等待别人主动唤醒等待别人唤醒 或 超时自动醒
典型方法synchronized 块入口wait() / join() / park()sleep() / wait(时间) / join(时间)
持有锁情况不持有(没抢到)不持有(已经释放)不持有(已经释放)
被唤醒方式锁释放后自动竞争notify / notifyAll / unparknotify / 超时 / unpark

二、线程状态转换图(最经典的 7 条转换路径)

new Thread() ↓ NEW ↓ start() RUNNABLE ←──────────────┐ / ↑ \ │ / │ \ │ CPU 时间片用完 / yield() 运行中 ←───── 就绪 等待锁 │ \ │ / │ \ ↓ / │ BLOCKED ←──── WAITING ←── TIMED_WAITING ↑ ↑ ↑ │ │ │ notify/notifyAll wait() sleep(时间)/wait(时间) │ │ │ └────────┴─────────────┘ ↓ TERMINATED

最常考的几条路径解释(通俗版)

  1. NEW → RUNNABLE
    调用start(),线程进入就绪队列排队等 CPU(不是立刻执行)

  2. RUNNABLE → TERMINATED
    run() 方法正常结束 或 抛出未捕获异常

  3. RUNNABLE → BLOCKED
    线程想进synchronized同步块,但发现锁被别人拿着 → 进入阻塞队列

  4. RUNNABLE → WAITING

    • obj.wait()(必须先持有锁)
    • thread.join()(等待目标线程结束)
    • LockSupport.park()
  5. RUNNABLE → TIMED_WAITING

    • Thread.sleep(毫秒)(最常见,不释放锁)
    • obj.wait(毫秒)
    • thread.join(毫秒)
    • LockSupport.parkNanos()/parkUntil()
  6. WAITING / TIMED_WAITING → RUNNABLE

    • notify/notifyAll唤醒(但不一定马上拿到锁)
    • unpark唤醒
    • 等待时间到(自动唤醒)
  7. BLOCKED → RUNNABLE
    锁被释放后,JVM 从阻塞队列里挑一个线程去竞争锁(不保证公平)

三、Java 内存模型(JMM)最核心的几件事(通俗版)

JMM 主要解决两个问题:

  1. 可见性(一个线程改了变量,另一个线程看不看得见)
  2. 有序性(代码写的顺序和实际执行顺序是否一致)

最核心的三个概念 + 一张图

1. 主内存 vs 工作内存

每个线程都有自己的工作内存(本地内存),里面放的是主内存变量的副本

主内存(共享) age = 18 money = 1000 ↑ ↑ ┌───────────────┬───────────────┐ │ 线程A工作内存 │ 线程B工作内存 │ │ age副本=18 │ age副本=18 │ │ money副本=1000│ money副本=1000│ └───────────────┴───────────────┘
2. 八大原子操作(决定变量什么时候从主内存同步到工作内存)
操作含义谁发起
lock把主内存变量标记为线程独占线程
unlock把锁释放线程
read从主内存读取变量值线程
load把 read 的值放入工作内存副本线程
use线程使用工作内存中的变量副本线程
assign线程把值赋给工作内存中的变量副本线程
store把工作内存副本的值传回主内存线程
write把 store 的值写入主内存的变量线程
3. happens-before 规则(最重要!决定“能不能看到修改”)

只要满足下面任意一条,前面的写操作对后面的读操作可见

  1. 程序顺序规则:单线程内,按代码顺序执行
  2. 监视器锁规则:解锁 → 同一个锁的加锁
  3. volatile 变量规则:对 volatile 变量的写 → 后面的读
  4. 线程启动规则:Thread.start() → 线程内的任意操作
  5. 线程终止规则:线程内任意操作 → Thread.isAlive()=false / join()返回
  6. 线程中断规则:interrupt() → 检测到中断(抛异常或 isInterrupted=true)
  7. 对象终结规则:构造方法结束 → finalize() 开始
  8. 传递性:A 先于 B,B 先于 C → A 先于 C

最常考的几条通俗解释

  • 我对 volatile x 写了 100 → 后面任何线程读 x 都必须是 100
  • 我 synchronized 块里改了 age → 出块后别的线程进同一个锁的 synchronized 块一定能看到
  • 我调用 t.start() → t 线程里面的代码一定能看到 start() 之前的变量值

总结一句话口诀

线程状态:NEW → start → RUNNABLE ↔ BLOCKED / WAITING / TIMED_WAITING → TERMINATED
内存模型:每个线程有自己的工作内存 + 主内存,要想让别人看到修改,必须走 happens-before 桥梁(volatile、synchronized、start/join 等)

如果你现在能画出线程状态转换图 + 说出 volatile 为什么能保证可见性 + 举例 happens-before 的 3 个最常用规则,
那么这篇内容你就已经掌握 80% 了。

需要我再深入讲解哪一块?
比如:

  • volatile 底层实现(内存屏障 + Lock 前缀)
  • synchronized 升级过程(偏向锁→轻量级锁→重量级锁)
  • JMM 对 double/long 的非原子性处理
  • ThreadLocal 与内存泄漏

告诉我,我继续给你展开~

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/15 13:06:49

1小时搞定:用PLAYWRIGHT快速验证产品创意

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 开发一个快速验证产品创意的PLAYWRIGHT原型,功能包括:1.自动采集竞品关键页面截图 2.提取核心功能点对比 3.生成可视化对比报告 4.模拟用户旅程。要求支持配…

作者头像 李华
网站建设 2026/6/13 20:50:22

nTopology平台自动生成适配不同热源分布的流道拓扑。

🎓作者简介:科技自媒体优质创作者 🌐个人主页:莱歌数字-CSDN博客 💌公众号:莱歌数字(B站同名) 📱个人微信:yanshanYH 211、985硕士,从业16年 从…

作者头像 李华
网站建设 2026/6/10 18:23:27

传统调试vsAI辅助:修复SyntaxError的效率对比

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 创建一个对比测试工具,能够:1. 生成包含SyntaxError的测试代码样本;2. 记录人工修复这些错误所需的时间;3. 使用AI自动修复同样的错…

作者头像 李华
网站建设 2026/6/14 4:49:37

网上超市系统(源码+数据库+文档)

网上超市 目录 基于springboot vue网上超市系统 一、前言 二、系统功能演示 三、技术选型 四、其他项目参考 五、代码参考 六、测试参考 七、最新计算机毕设选题推荐 八、源码获取: 基于springboot vue网上超市系统 一、前言 博主介绍:✌️大…

作者头像 李华
网站建设 2026/6/13 14:55:40

Docker效率革命:比传统虚拟机快10倍的秘密

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 请设计一个性能对比实验方案:1. 准备相同的Web应用 2. 分别部署在Docker容器和VM虚拟机中 3. 测试启动时间、内存占用、CPU使用率和并发处理能力 4. 生成可视化对比图表…

作者头像 李华
网站建设 2026/6/13 1:59:44

KNIFE4J vs 传统文档工具:效率对比与优势分析

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 设计一个对比工具,展示KNIFE4J与传统API文档工具(如Postman、Swagger UI)在文档生成速度、易用性和功能丰富性方面的差异。要求工具能够自动生成…

作者头像 李华