# 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進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。