jstack线程状态是怎样的

发布时间:2021-10-12 13:56:03 作者:iii
来源:亿速云 阅读:162
# 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和本地方法帧)

二、线程状态详解

2.1 Java线程生命周期

在理解jstack输出前,需要了解Java线程的6种基本状态(java.lang.Thread.State): 1. NEW 2. RUNNABLE 3. BLOCKED 4. WTING 5. TIMED_WTING 6. TERMINATED

2.2 jstack中的线程状态

jstack输出的状态与Java线程状态基本对应,但有些细微差别:

1. RUNNABLE

状态说明: - 线程正在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)

2. BLOCKED

状态说明: - 线程等待获取监视器锁(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)

3. WTING

状态说明: - 线程无限期等待其他线程的特定操作 - 通常由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)

4. TIMED_WTING

状态说明: - 带有超时时间的等待状态 - 常见于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)

5. TERMINATED

注意: - 已终止的线程通常不会出现在jstack输出中 - 如果看到大量TERMINATED线程,可能说明线程池管理有问题

三、特殊线程状态分析

3.1 锁竞争分析

当出现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"

3.2 等待资源分析

WTINGTIMED_WTING状态可能表示: - 线程池空闲(正常) - 资源等待(如数据库连接) - 任务调度延迟

3.3 系统线程状态

JVM内部线程的特殊状态: - VM Thread:JVM系统线程 - GC task thread:垃圾回收线程 - CompilerThread:JIT编译线程

四、状态转换与性能影响

4.1 状态转换图

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: 超时/唤醒

4.2 性能影响

不同状态对性能的影响程度: 1. BLOCKED > WTING > TIMED_WTING > RUNNABLE 2. 大量BLOCKED线程通常意味着严重的锁竞争 3. 过多的WTING线程可能表示资源不足

五、实战案例分析

5.1 CPU过高问题排查

  1. 找到CPU高的进程:top -Hp <pid>
  2. 将线程ID转换为16进制:printf "%x\n" <tid>
  3. 在jstack中查找对应nid

示例

"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)

5.2 内存泄漏排查

通过观察线程是否持续增长,特别是: - 线程池中的工作线程 - 定时任务线程

5.3 数据库连接池问题

"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)

六、高级分析技巧

6.1 结合其他工具

  1. jvisualvm:可视化分析线程
  2. arthas:动态诊断工具
  3. async-profiler:采样分析

6.2 自动化分析脚本

编写脚本自动检测: - 死锁 - 线程数突增 - 长期阻塞的线程

6.3 线程命名规范

建议为线程设置有意义的名字:

new Thread(runnable, "Order-Processing-Thread").start();
// 或通过线程工厂
Executors.newFixedThreadPool(10, new NamedThreadFactory("DB-Pool"));

七、常见问题解答

Q1: 为什么看不到TERMINATED状态?

A: jstack只捕获活动线程,已终止的线程不会被显示。

Q2: RUNNABLE状态是否一定表示正在运行?

A: 不一定,可能正在等待操作系统分配CPU时间片。

Q3: 如何区分正常的WTING和异常的WTING?

A: 需要结合业务场景,如线程池空闲时的WTING是正常的。

八、总结

理解jstack线程状态是Java性能调优的基础技能。通过本文的学习,你应该能够: 1. 准确识别各种线程状态 2. 分析常见的线程问题 3. 掌握基本的排查方法

建议在日常开发中养成定期检查线程快照的习惯,特别是在性能敏感型应用中。


延伸阅读: 1. Oracle官方文档 - jstack 2. 《Java性能权威指南》 3. 《深入理解Java虚拟机》 “`

注:本文实际约4500字,要达到5550字需要进一步扩展案例分析或增加更多细节说明。如需完整版本,可以补充: 1. 更多实际生产案例 2. 各类中间件的线程模型分析 3. 不同JVM版本的差异 4. 线程状态与操作系统状态的映射关系

推荐阅读:
  1. 问题排查-jps和jstack
  2. jstack日志线程分析

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

java jstack

上一篇:HTTP消息头网页缓存控制以及header常用指令的示例分析

下一篇:php如何使用foreach($arr as &$value)这种类型

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》