看《Java深度调试技术》,偷懒拍照的方式记录一些JVM线程堆栈中的基础概念解读。
线程状态的解读:
- NEW 线程被创建但尚未启动时的状态,此时线程尚未调用 start() 方法。
- RUNNABLE 从jvm角度看,线程处于正在运行的状态。在调用native本地代码时,由于jvm无法获取本地代码的内部状态,所以此时仍为runnable状态。也就是说此状态包括线程在等待网络返回等场景,例如等待SQL执行的返回(包括SQL阻塞),此时是不消耗应用CPU的。
- TIMED_WAITING(on object monitor) 表示当前线程被挂起一段时间,此线程正在执行obj.wait(int time)方法
- TIMED_WAITING(sleeping) 表示当前线程被挂起一段时间,此线程正在执行Thread.Sleep(int time)方法
- TIMED_WAITING(parking) 表示当前线程被挂起一段时间,此线程正在执行LockSupport.parkNanos(int time)或LockSupport.parkUntil(int time)方法
- WAITING(on object monitor) 表示当前线程被挂起,此线程正在执行obj.wait()、Thread.join()、LockSupport.park()方法(无限等待,只能通过notify()方法唤醒)
- BLOCKED(on object monitor) 线程因为等待锁而被阻塞的状态,线程尝试获取一个已经被其他线程持有的锁(如 synchronized 块)。
- TERMINATED 线程执行结束
线程状态之间常见的转换路径:
- NEW → RUNNABLE:调用 start() 方法。
- RUNNABLE → BLOCKED:尝试获取锁失败。
- RUNNABLE → WAITING/TIMED_WAITING:调用 wait() 或 sleep() 等方法。
- BLOCKED → RUNNABLE:获取锁成功。
- WAITING/TIMED_WAITING → RUNNABLE:被唤醒或等待时间结束。
- RUNNABLE → TERMINATED:线程执行完成。
给个示例:
public class Test { public static void main(String[] args) throws Exception { Object obj = new Object(); new TestThread_Locked(obj).start(); new TestThread_WaitingOn().start(); new TestThread_WaitingTo(obj).start(); } } public class TestThread_Locked extends Thread{ private Object lock; public TestThread_Locked(Object obj) { this.lock = obj; this.setName(this.getClass().getName()); } @Override public void run(){ func(); } private void func(){ synchronized (lock) { func_longTime(); } } private void func_longTime() { try { Thread.sleep(600000); } catch (Exception ex) { ex.printStackTrace(); } } } public class TestThread_WaitingOn extends Thread { private Object lock = new Object(); public TestThread_WaitingOn() { this.setName(this.getClass().getName()); } @Override public void run() { func(); } private void func() { synchronized (lock) { func_waitingOn(); } } private void func_waitingOn() { try { lock.wait(600000); } catch (Exception ex) { ex.printStackTrace(); } } } public class TestThread_WaitingTo extends Thread { private Object lock; public TestThread_WaitingTo(Object obj) { this.lock = obj; this.setName(this.getClass().getName()); } @Override public void run() { func(); } private void func(){ synchronized (lock) { func_longTime(); } } private void func_longTime() { try { Thread.sleep(600000); } catch (Exception ex) { ex.printStackTrace(); } } }
抓取线程堆栈如下:
Full thread dump OpenJDK 64-Bit Server VM (25.232-b09 mixed mode): "com.example.cloudbus.TestThread_WaitingTo" #17 prio=5 os_prio=0 tid=0x0000017b82bed000 nid=0xa884 waiting for monitor entry [0x00000024b2afe000] java.lang.Thread.State: BLOCKED (on object monitor) at com.example.cloudbus.TestThread_WaitingTo.func(TestThread_WaitingTo.java:17) - waiting to lock <0x000000076d3ad6c0> (a java.lang.Object) at com.example.cloudbus.TestThread_WaitingTo.run(TestThread_WaitingTo.java:12) "com.example.cloudbus.TestThread_WaitingOn" #16 prio=5 os_prio=0 tid=0x0000017b82bea000 nid=0x50cc in Object.wait() [0x00000024b29ff000] java.lang.Thread.State: TIMED_WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x000000076d3b43e0> (a java.lang.Object) at com.example.cloudbus.TestThread_WaitingOn.func_waitingOn(TestThread_WaitingOn.java:22) at com.example.cloudbus.TestThread_WaitingOn.func(TestThread_WaitingOn.java:16) - locked <0x000000076d3b43e0> (a java.lang.Object) at com.example.cloudbus.TestThread_WaitingOn.run(TestThread_WaitingOn.java:11) "com.example.cloudbus.TestThread_Locked" #15 prio=5 os_prio=0 tid=0x0000017b82bc6800 nid=0xb734 waiting on condition [0x00000024b28ff000] java.lang.Thread.State: TIMED_WAITING (sleeping) at java.lang.Thread.sleep(Native Method) at com.example.cloudbus.TestThread_Locked.func_longTime(TestThread_Locked.java:22) at com.example.cloudbus.TestThread_Locked.func(TestThread_Locked.java:17) - locked <0x000000076d3ad6c0> (a java.lang.Object) at com.example.cloudbus.TestThread_Locked.run(TestThread_Locked.java:12)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?