方法分類總覽
| 方法 | 所屬類別 | 靜態/實例 | 釋放鎖 | 主要用途 |
| start() | Thread | 實例 | 否 | 啟動新執行緒 |
| run() | Thread/Runnable | 實例 | 否 | 執行緒主體邏輯 |
| sleep() | Thread | 靜態 | 否 | 延遲指定時間 |
| yield() | Thread | 靜態 | 否 | 讓出 CPU |
| join() | Thread | 實例 | 否 | 等待執行緒結束 |
| wait() | Object | 實例 | 是 | 等待條件滿足 |
| notify() | Object | 實例 | 否 | 喚醒單一等待者 |
| notifyAll() | Object | 實例 | 否 | 喚醒所有等待者 |
核心方法詳細解析
start() vs run()
start():建立新執行緒,由 JVM 調度稍後呼叫 run()
run():普通方法呼叫,不會建立新執行緒,在當前執行緒同步執行
- 錯誤範例:
new MyThread().run() → 單執行緒循序執行
sleep(millis)
- 靜態方法,當前執行緒休眠指定毫秒
- 不釋放鎖,持有 synchronized 鎖時睡眠會阻塞其他執行緒
- 必須捕獲
InterruptedException
- 精度受 OS 排程影響,非即時系統無保證
join() / join(millis)
- 等待目標執行緒終止
- 底層實作為
wait() 迴圈
- 逾時版本避免無限等待
yield()
- 提示排程器當前執行緒願讓出 CPU
- 僅對同優先級執行緒有機會
- 不保證立即切換,視 JVM 實作而定
wait/notify/notifyAll (Object 方法)
- 必須在 synchronized(lock) 區塊內呼叫
wait():釋放鎖,進入 lock 的等待集合
notify():隨機喚醒一個等待者,移至鎖等待隊列
notifyAll():喚醒所有等待者
- 喚醒後需重新獲得鎖才能繼續執行
經典生產者/消費者模式
class Buffer {
private final List queue = new ArrayList<>();
private final int capacity;
Buffer(int cap) { capacity = cap; }
synchronized void put(int value) throws InterruptedException {
while (queue.size() == capacity) wait(); // 滿等待
queue.add(value);
notifyAll(); // 通知消費者
}
synchronized int take() throws InterruptedException {
while (queue.isEmpty()) wait(); // 空等待
int val = queue.remove(0);
notifyAll(); // 通知生產者
return val;
}
}
關鍵注意事項
- 虛假喚醒:
wait() 應在 while (condition) 迴圈中
- 鎖物件一致性:wait/notify 必須同一物件鎖
- notify vs notifyAll:單條件用 notify,多條件必須 notifyAll
- Thread 類別方法 vs Object 方法:sleep/yield/start 屬 Thread;wait/notify 屬 Object