您好,登录后才能下订单哦!
# jstack线程状态是怎样的
## 引言
在Java应用性能分析和故障排查过程中,`jstack`是一个不可或缺的工具。它能够生成Java虚拟机(JVM)中所有线程的快照,帮助我们了解线程的运行状态、调用栈信息以及潜在的线程问题。本文将深入探讨`jstack`输出的线程状态,帮助开发者更好地理解和分析线程行为。
## 一、jstack简介
### 1.1 什么是jstack
`jstack`是JDK自带的一个命令行工具,用于生成Java虚拟机当前时刻的线程快照(thread dump)。通过线程快照,我们可以:
- 查看所有线程的调用栈
- 分析线程状态
- 定位死锁、线程阻塞等问题
### 1.2 基本使用方法
```bash
jstack [options] <pid>
常用选项:
- -l
:显示额外的锁信息
- -F
:强制生成线程快照(当jstack无响应时使用)
- -m
:混合模式(显示Java和本地方法帧)
在理解jstack
输出前,需要了解Java线程的6种基本状态(java.lang.Thread.State
):
1. NEW
2. RUNNABLE
3. BLOCKED
4. WTING
5. TIMED_WTING
6. TERMINATED
jstack
输出的状态与Java线程状态基本对应,但有些细微差别:
状态说明: - 线程正在JVM中执行或等待操作系统资源(如CPU时间片) - 可能正在运行,也可能处于就绪状态
典型场景:
"main" #1 prio=5 os_prio=0 tid=0x00007f8b4800a800 nid=0x1a03 runnable [0x00007f8b4c7e7000]
java.lang.Thread.State: RUNNABLE
at java.io.FileInputStream.readBytes(Native Method)
at java.io.FileInputStream.read(FileInputStream.java:255)
状态说明: - 线程等待获取监视器锁(synchronized) - 发生在同步块/方法中
典型场景:
"Thread-1" #12 prio=5 os_prio=0 tid=0x00007f8b4818f000 nid=0x1a1f waiting for monitor entry [0x00007f8b3c7e7000]
java.lang.Thread.State: BLOCKED (on object monitor)
at com.example.DeadLock.run(DeadLock.java:20)
- waiting to lock <0x000000076b98d0c0> (a java.lang.Object)
状态说明:
- 线程无限期等待其他线程的特定操作
- 通常由wait()
、join()
或LockSupport.park()
引起
典型场景:
"Thread-2" #13 prio=5 os_prio=0 tid=0x00007f8b48190800 nid=0x1a20 waiting on condition [0x00007f8b3c6e6000]
java.lang.Thread.State: WTING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x000000076b98d0d0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
状态说明:
- 带有超时时间的等待状态
- 常见于sleep()
、wait(timeout)
、join(timeout)
等
典型场景:
"Thread-3" #14 prio=5 os_prio=0 tid=0x00007f8b48192000 nid=0x1a21 waiting on condition [0x00007f8b3c5e5000]
java.lang.Thread.State: TIMED_WTING (sleeping)
at java.lang.Thread.sleep(Native Method)
at com.example.TimedTask.run(TimedTask.java:15)
注意: - 已终止的线程通常不会出现在jstack输出中 - 如果看到大量TERMINATED线程,可能说明线程池管理有问题
当出现BLOCKED
状态时,需要关注:
- 锁对象的地址(如<0x000000076b98d0c0>
)
- 持有锁的线程(通过-l
选项查看)
死锁示例:
Found one Java-level deadlock:
=============================
"Thread-1":
waiting to lock monitor 0x00007f8b4800a800 (object 0x000000076b98d0c0, a java.lang.Object),
which is held by "Thread-2"
"Thread-2":
waiting to lock monitor 0x00007f8b4800b800 (object 0x000000076b98d0d0, a java.lang.Object),
which is held by "Thread-1"
WTING
和TIMED_WTING
状态可能表示:
- 线程池空闲(正常)
- 资源等待(如数据库连接)
- 任务调度延迟
JVM内部线程的特殊状态:
- VM Thread
:JVM系统线程
- GC task thread
:垃圾回收线程
- CompilerThread
:JIT编译线程
stateDiagram
[*] --> NEW
NEW --> RUNNABLE: start()
RUNNABLE --> TERMINATED: 运行完成
RUNNABLE --> BLOCKED: 等待锁
BLOCKED --> RUNNABLE: 获取锁
RUNNABLE --> WTING: wait()/join()
WTING --> RUNNABLE: notify()/notifyAll()
RUNNABLE --> TIMED_WTING: sleep()/wait(timeout)
TIMED_WTING --> RUNNABLE: 超时/唤醒
不同状态对性能的影响程度: 1. BLOCKED > WTING > TIMED_WTING > RUNNABLE 2. 大量BLOCKED线程通常意味着严重的锁竞争 3. 过多的WTING线程可能表示资源不足
top -Hp <pid>
printf "%x\n" <tid>
示例:
"HighCpuThread" #15 prio=5 os_prio=0 tid=0x00007f8b48193800 nid=0x1a22 runnable [0x00007f8b3c4e4000]
java.lang.Thread.State: RUNNABLE
at com.example.HighCpuTask.run(HighCpuTask.java:10)
通过观察线程是否持续增长,特别是: - 线程池中的工作线程 - 定时任务线程
"pool-1-thread-1" #16 prio=5 os_prio=0 tid=0x00007f8b48195000 nid=0x1a23 waiting on condition [0x00007f8b3c3e3000]
java.lang.Thread.State: WTING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x000000076b98d0e0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at com.mysql.jdbc.ConnectionImpl.waitForLock(ConnectionImpl.java:4256)
编写脚本自动检测: - 死锁 - 线程数突增 - 长期阻塞的线程
建议为线程设置有意义的名字:
new Thread(runnable, "Order-Processing-Thread").start();
// 或通过线程工厂
Executors.newFixedThreadPool(10, new NamedThreadFactory("DB-Pool"));
A: jstack只捕获活动线程,已终止的线程不会被显示。
A: 不一定,可能正在等待操作系统分配CPU时间片。
A: 需要结合业务场景,如线程池空闲时的WTING是正常的。
理解jstack线程状态是Java性能调优的基础技能。通过本文的学习,你应该能够: 1. 准确识别各种线程状态 2. 分析常见的线程问题 3. 掌握基本的排查方法
建议在日常开发中养成定期检查线程快照的习惯,特别是在性能敏感型应用中。
延伸阅读: 1. Oracle官方文档 - jstack 2. 《Java性能权威指南》 3. 《深入理解Java虚拟机》 “`
注:本文实际约4500字,要达到5550字需要进一步扩展案例分析或增加更多细节说明。如需完整版本,可以补充: 1. 更多实际生产案例 2. 各类中间件的线程模型分析 3. 不同JVM版本的差异 4. 线程状态与操作系统状态的映射关系
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。