news 2026/2/9 20:31:59

一文搞懂线程状态转换与 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/2/8 2:31:11

快速验证:用中文Cursor一小时打造天气APP

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 开发一个基于Python的天气查询应用原型,要求:1. 全程使用中文版Cursor 2. 展示AI生成代码过程 3. 包含API调用和UI设计 4. 可一键运行的完整项目。使用Flas…

作者头像 李华
网站建设 2026/2/9 20:31:38

企业级SVN解决方案:TORTOISESVN下载与团队协作实战

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 开发一个企业SVN环境配置演示应用,包含以下场景:1) TORTOISESVN多版本并行下载 2) Visual Studio集成配置 3) 典型分支策略实施 4) 权限模板生成器 5) 变更…

作者头像 李华
网站建设 2026/2/8 18:58:52

零基础入门:10分钟学会Postman在线测试API

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 开发一个面向新手的Postman在线版交互式教程,从创建第一个请求开始,逐步讲解如何发送请求、查看响应、使用环境变量、编写简单测试脚本等基础功能。教程包含…

作者头像 李华
网站建设 2026/2/7 13:49:42

企业级Proxmox集群部署实战:从裸机到高可用

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 创建一个企业级Proxmox集群部署指南,包含:1.3节点服务器硬件规格建议 2.详细的Ceph分布式存储配置流程 3.CorosyncPacemaker高可用方案 4.虚拟机迁移测试步…

作者头像 李华
网站建设 2026/2/9 23:48:54

咖啡馆管理系统|基于springboot 咖啡馆管理系统(源码+数据库+文档)

咖啡馆管理系统 目录 基于springboot vue咖啡馆管理系统 一、前言 二、系统功能演示 三、技术选型 四、其他项目参考 五、代码参考 六、测试参考 七、最新计算机毕设选题推荐 八、源码获取: 基于springboot vue咖啡馆管理系统 一、前言 博主介绍&#x…

作者头像 李华
网站建设 2026/2/8 23:45:17

小白必看:HOSTS文件在哪?图文详解

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 制作一个交互式HOSTS文件查找教程应用,包含:1. 系统选择界面(Windows/macOS/Linux)2. 分步骤动画演示 3. 实时操作指引 4. 常见问题…

作者头像 李华