news 2026/4/16 17:45:02

一文搞懂线程状态转换与 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/4/16 14:29:39

减速器十年演进

过去十年(2015–2025),工业减速器从“高可靠机械传动部件”演进为“面向机器人、自动化与新能源的高精度、智能化传动系统”;未来十年(2025–2035),减速器将以高精度、轻量化与数字化为主线&…

作者头像 李华
网站建设 2026/4/16 16:12:31

用JDK1.7快速构建原型:Web服务示例

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 生成一个基于JDK1.7的轻量级Web服务原型,要求:1. 使用内置HttpServer实现REST接口;2. 包含简单的数据持久化功能;3. 支持JSON格式请…

作者头像 李华
网站建设 2026/4/16 10:50:45

工业案例:PINN在油气藏模拟中的颠覆性应用

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 构建油气藏渗流PINN模型。输入:地质参数(渗透率分布、孔隙度)、生产井数据。输出:1) 压力场动态预测网络 2) 产能预测模块 3) 可视化…

作者头像 李华
网站建设 2026/4/16 11:01:32

EfficientNet解析:AI如何优化深度学习模型架构

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 使用EfficientNet构建一个图像分类模型,要求:1.采用复合缩放方法自动优化模型架构 2.支持多种分辨率输入 3.包含模型压缩功能 4.提供不同规模的预训练模型(…

作者头像 李华
网站建设 2026/4/16 12:31:46

SpringDoc vs 传统Swagger:效率对比分析

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 创建一个对比项目,分别使用SpringDoc-OpenAPI和传统Swagger生成API文档。要求:1. 相同的Controller代码;2. 对比配置复杂度;3. 对比…

作者头像 李华
网站建设 2026/4/16 13:56:47

小白必看:5分钟搭建你的第一个网盘搜索工具

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 创建一个极简的网盘资源搜索工具教程项目,使用现成的API接口实现基本搜索功能。前端只需一个搜索框和结果列表,后端调用公开的网盘搜索API。提供详细的步骤…

作者头像 李华