| 方法 | 說明 |
sleep(long ms) | 靜態方法,讓當前線程休眠指定毫秒,不釋放鎖。 |
join() | 等待目標線程終止,當前線程阻塞。 |
yield() | 靜態方法,提示調度器當前線程願意讓出 CPU,非強制。 |
setDaemon(true) | 標記為守護線程(需在 start() 前呼叫)。僅剩守護線程時 JVM 退出。 |
interrupt() | 中斷線程:阻塞狀態拋 InterruptedException;運行狀態設中斷旗標,需自行檢查 isInterrupted()。 |
stop() | 已棄用,強制終止導致資料不一致。 |
線程生命週期
六狀態:NEW → RUNNABLE → BLOCKED/WAITING/TIMED_WAITING → TERMINATED。狀態轉換圖:

線程安全與同步機制
問題根因(三要素)
- 多線程環境
- 共享資料
- 多條語句操作共享資料(非原子)
經典售票案例:sleep(100) 放大並發衝突,導致重賣、負票。
同步解決方案
- 同步程式碼塊:
synchronized(obj) { ... },鎖為任意物件。
- 同步方法:
synchronized void method(),鎖為 this。
- 靜態同步方法:鎖為當前類別
Class 物件。
線程安全集合類別:StringBuffer、Vector、Hashtable。非安全集合可用 Collections.synchronizedXxx() 包裝。
JDK 5+ 顯式鎖
private Lock lock = new ReentrantLock();
public void run() {
while (true) {
try {
lock.lock();
if (tickets > 0) { /* 賣票邏輯 */ }
} finally {
lock.unlock(); // 必須在 finally 釋放
}
}
}
ReentrantLock 支援公平/非公平模式、條件變數(Condition)、可中斷鎖獲取等進階功能。
死鎖與避免
兩線程互相持有對方所需鎖(巢狀 synchronized 且鎖順序相反)。避免策略:固定全域鎖獲取順序、使用 tryLock(timeout)、縮小鎖範圍。
生產者-消費者(等待/通知機制)
wait():線程釋放鎖進入等待集合,被喚醒後重新競爭鎖繼續執行。
notify():喚醒單一等待線程(轉 RUNNABLE)。
notifyAll():喚醒所有等待線程(多生產多消費必須)。
定義於 Object,因鎖對象任意,需透過鎖對象呼叫。最佳實踐:將同步、等待、通知封裝於資源類別內部。
進階特性
線程組
ThreadGroup 批量管理線程。預設屬 main 組。可建立自訂組並設為守護組(tg.setDaemon(true))。
線程池
降低頻繁建立/銷毀線程開銷(涉及 OS 互動)。Executors 工廠:
newCachedThreadPool():可緩存線程,適合大量短生命任務。
newFixedThreadPool(n):固定大小,可重用。
newSingleThreadExecutor():單線程序列化執行。
ExecutorService 提交 Runnable/Callable 回傳 Future。shutdown() 有序關閉。
匿名內部類快速建立線程
new Thread() { public void run() { ... } }.start();
new Thread(new Runnable() { public void run() { ... } }).start();
定時器應用
Timer 排程 TimerTask(run() 定義任務),支援單次/週期執行。生產環境推薦 Quartz 框架(功能更豐富、支援叢集)。
- 上一篇文章: Java 集合深度剖析(二):List 介面與 ArrayList、LinkedList 實作原理
- 下一篇文章: Apache Lucene 全文檢索引擎實戰(一):索引建立核心流程詳解
Copyright ©
程式碼之家 All Rights Reserved