# Java中怎么實現線程狀態的切換
## 目錄
1. [線程狀態概述](#線程狀態概述)
2. [新建狀態(NEW)](#新建狀態new)
3. [可運行狀態(RUNNABLE)](#可運行狀態runnable)
4. [阻塞狀態(BLOCKED)](#阻塞狀態blocked)
5. [等待狀態(WTING)](#等待狀態waiting)
6. [計時等待狀態(TIMED_WTING)](#計時等待狀態timed_waiting)
7. [終止狀態(TERMINATED)](#終止狀態terminated)
8. [狀態切換實戰案例](#狀態切換實戰案例)
9. [狀態監控與診斷](#狀態監控與診斷)
10. [常見問題與解決方案](#常見問題與解決方案)
11. [最佳實踐](#最佳實踐)
12. [總結](#總結)
<a name="線程狀態概述"></a>
## 1. 線程狀態概述
Java線程在其生命周期中會經歷6種不同的狀態,這些狀態在`java.lang.Thread.State`枚舉中明確定義:
```java
public enum State {
NEW,
RUNNABLE,
BLOCKED,
WTING,
TIMED_WTING,
TERMINATED
}
狀態轉換圖示:
stateDiagram
[*] --> NEW
NEW --> RUNNABLE: start()
RUNNABLE --> TERMINATED: 執行完成/異常退出
RUNNABLE --> WTING: wait()/join()/park()
WTING --> RUNNABLE: notify()/notifyAll()/unpark()
RUNNABLE --> TIMED_WTING: sleep()/wait(timeout)/join(timeout)
TIMED_WTING --> RUNNABLE: 超時/喚醒
RUNNABLE --> BLOCKED: 競爭同步鎖
BLOCKED --> RUNNABLE: 獲取鎖成功
Thread.getState()
返回Thread.State.NEW
// 方式1:繼承Thread類
class MyThread extends Thread {
public void run() {
System.out.println("Thread running");
}
}
// 方式2:實現Runnable接口
Runnable task = () -> System.out.println("Runnable running");
// 創建線程對象
Thread thread1 = new MyThread();
Thread thread2 = new Thread(task);
Thread thread = new Thread(() -> {});
System.out.println(thread.getState()); // 輸出 NEW
thread.start(); // 轉換為RUNNABLE狀態
Thread thread = new Thread(() -> {
// 線程執行體
});
thread.start(); // 進入RUNNABLE狀態
Thread thread = new Thread(() -> {
try {
Thread.sleep(1000); // 進入TIMED_WTING
} catch (InterruptedException e) {
e.printStackTrace();
}
});
thread.start();
System.out.println(thread.getState()); // RUNNABLE
synchronized
同步鎖失敗Object lock = new Object();
Thread t1 = new Thread(() -> {
synchronized (lock) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread t2 = new Thread(() -> {
synchronized (lock) { // 此處會阻塞
System.out.println("獲得鎖");
}
});
t1.start();
Thread.sleep(100); // 確保t1先獲得鎖
t2.start();
Thread.sleep(100);
System.out.println(t2.getState()); // BLOCKED
Object.wait()
Thread.join()
LockSupport.park()
Object monitor = new Object();
Thread t = new Thread(() -> {
synchronized (monitor) {
try {
monitor.wait(); // 進入WTING
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t.start();
Thread.sleep(100);
System.out.println(t.getState()); // WTING
Thread.sleep(long)
Object.wait(long)
Thread.join(long)
LockSupport.parkNanos()
LockSupport.parkUntil()
Thread t = new Thread(() -> {
try {
Thread.sleep(2000); // TIMED_WTING
} catch (InterruptedException e) {
e.printStackTrace();
}
});
t.start();
Thread.sleep(100);
System.out.println(t.getState()); // TIMED_WTING
Thread.stop()
(已廢棄)Thread t = new Thread(() -> {});
t.start();
t.join(); // 等待線程結束
System.out.println(t.getState()); // TERMINATED
class Buffer {
private Queue<Integer> queue = new LinkedList<>();
private int capacity;
public Buffer(int capacity) {
this.capacity = capacity;
}
public synchronized void produce(int item) throws InterruptedException {
while (queue.size() == capacity) {
wait(); // 進入WTING
}
queue.add(item);
notifyAll(); // 喚醒消費者
}
public synchronized int consume() throws InterruptedException {
while (queue.isEmpty()) {
wait(); // 進入WTING
}
int item = queue.poll();
notifyAll(); // 喚醒生產者
return item;
}
}
ExecutorService executor = Executors.newFixedThreadPool(2);
Future<?> future = executor.submit(() -> {
Thread.sleep(1000);
return "Done";
});
// 監控任務狀態
while (!future.isDone()) {
System.out.println("任務執行中...");
Thread.sleep(200);
}
System.out.println("任務完成");
jstack <pid> > thread_dump.txt
"main" #1 prio=5 os_prio=0 tid=0x00007f4874009800 nid=0xa waiting on condition [0x00007f487b4a6000]
java.lang.Thread.State: TIMED_WTING (sleeping)
at java.lang.Thread.sleep(Native Method)
at com.example.App.main(App.java:10)
// 死鎖示例
Object lock1 = new Object();
Object lock2 = new Object();
new Thread(() -> {
synchronized (lock1) {
try { Thread.sleep(100); } catch (Exception e) {}
synchronized (lock2) {
System.out.println("Thread1");
}
}
}).start();
new Thread(() -> {
synchronized (lock2) {
synchronized (lock1) {
System.out.println("Thread2");
}
}
}).start();
解決方案:
- 使用tryLock()
設置超時
- 統一加鎖順序
- 使用更高級的并發工具
優先使用并發工具類:
ExecutorService executor = Executors.newCachedThreadPool();
Future<String> future = executor.submit(() -> "result");
避免直接操作線程狀態:
suspend()/resume()/stop()
合理設置線程優先級:
thread.setPriority(Thread.NORM_PRIORITY);
使用線程安全集合:
List<String> syncList = Collections.synchronizedList(new ArrayList<>());
Java線程狀態管理是并發編程的核心基礎,本文詳細分析了: - 6種線程狀態的特性與轉換條件 - 各種狀態切換的代碼實現方式 - 實際開發中的狀態監控技巧 - 常見問題的解決方案 - 線程編程的最佳實踐
掌握這些知識將幫助開發者編寫出更健壯、高效的并發程序。
本文共計約9650字,詳細覆蓋了Java線程狀態切換的各個方面。實際開發中應當根據具體場景選擇合適的線程管理策略,并充分利用現代Java并發工具簡化開發。 “`
注:由于篇幅限制,這里展示的是精簡后的文章框架和核心內容示例。完整的9650字文章需要在此基礎上擴展以下內容: 1. 每種狀態的更詳細解釋和子狀態分析 2. 更多實際應用場景的代碼示例 3. 性能優化相關建議 4. 不同Java版本的特性差異 5. 更深入的狀態機轉換分析 6. 與操作系統線程狀態的對比 7. 完整的故障排查案例等
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。