| 屬性 | 獲取方法 | 設置方法 | 說明 |
|---|---|---|---|
| ID | getId() | 不可設置 | JVM 分配的唯一長整型標識 |
| Name | getName() | setName() | 默認 "Thread-N",強烈建議業務語義命名 |
| Priority | getPriority() | setPriority(1-10) | 1=MIN, 5=NORM, 10=MAX,**僅提示調度器,不保證** |
| State | getState() | 不可設置 | 六大狀態:NEW/RUNNABLE/BLOCKED/WAITING/TIMED_WAITING/TERMINATED |
| Daemon | isDaemon() | setDaemon(true) | 守護線程:JVM 退出時不等待,必須在 start() 前設置 |
| ThreadGroup | getThreadGroup() | 構造時指定 | 線程組管理,現已較少使用 |
public class ThreadMonitorDemo {
private static final Logger LOG = LoggerFactory.getLogger(ThreadMonitorDemo.class);
public static void main(String[] args) throws IOException {
int n = 10;
Thread[] threads = new Thread[n];
Thread.State[] lastStates = new Thread.State[n];
// 1. 創建並配置線程
for (int i = 0; i < n; i++) {
final int num = i;
Runnable task = () -> {
for (int j = 0; j < 10; j++) {
System.out.printf("%s: %d * %d = %d%n",
Thread.currentThread().getName(), num, j, num * j);
}
};
threads[i] = new Thread(task, "Worker-" + i);
// 奇數高優先級,偶數低優先級
threads[i].setPriority(i % 2 == 0 ? Thread.MAX_PRIORITY : Thread.MIN_PRIORITY);
lastStates[i] = threads[i].getState(); // NEW
}
// 2. 記錄初始狀態
try (PrintWriter pw = new PrintWriter(new FileWriter("thread-state.log"))) {
for (int i = 0; i < n; i++) {
pw.printf("MAIN: Thread[%d] %s INIT_STATE=%s%n", i, threads[i].getName(), lastStates[i]);
}
// 3. 批量啟動
for (Thread t : threads) t.start();
// 4. 輪詢監控狀態變化(生產環境建議用 JMX/Actuator)
boolean allTerminated = false;
while (!allTerminated) {
allTerminated = true;
for (int i = 0; i < n; i++) {
Thread.State current = threads[i].getState();
if (current != lastStates[i]) {
pw.printf("MAIN: Thread[%d] %s STATE_CHANGE: %s -> %s%n",
i, threads[i].getName(), lastStates[i], current);
lastStates[i] = current;
}
if (current != Thread.State.TERMINATED) allTerminated = false;
}
// 避免忙等佔用 CPU,實際可用 LockSupport.parkNanos(10_000_000)
Thread.sleep(10);
}
pw.println("MAIN: All threads terminated.");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
MAIN: Thread[0] Worker-0 INIT_STATE=NEW
MAIN: Thread[1] Worker-1 INIT_STATE=NEW
...
MAIN: Thread[0] Worker-0 STATE_CHANGE: NEW -> RUNNABLE
MAIN: Thread[2] Worker-2 STATE_CHANGE: NEW -> RUNNABLE
...
MAIN: Thread[0] Worker-0 STATE_CHANGE: RUNNABLE -> TERMINATED
MAIN: Thread[2] Worker-2 STATE_CHANGE: RUNNABLE -> TERMINATED
...
MAIN: All threads terminated.
觀察現象:高優先級線程(Worker-0,2,4...)傾向於更早進入 TERMINATED,但不保證絕對順序,受操作系統調度器影響。
/actuator/metrics/jvm.threads.states 直接暴露各狀態計數;thread -n 10 實時查看前 10 忙碌線程堆棧;findDeadlockedThreads()。⚠️ 警告:
Thread.setPriority()只是向操作系統調度器的提示,不保證執行順序。過度依賴優先級會導致:
- 饑餓:低優先級線程長期得不到 CPU;
- 優先級反轉:高優先級等待低優先級持有的鎖;
- 跨平台行為差異:Windows/Linux 對優先級映射不同。
建議:業務代碼保持默認優先級 (NORM_PRIORITY);真正需要調度控制時,使用 線程池隔離(不同業務用不同線程池)、信號量/鎖公平性、CompletableFuture 優先級隊列 等結構化手段。
biz-module-action-index,如 order-pay-callback-3,便於日誌/Arthas 定位;