Thread.sleep(millis) 讓**當前執行緒**進入 **TIMED_WAITING** 狀態,指定時間後自動轉為 **RUNNABLE** 等待 CPU 調度。**關鍵特性:不釋放同步鎖 (monitor)**,這與 Object.wait() 根本不同。
// 靜態方法,作用於「當前線程」
Thread.sleep(1000); // 睡 1 秒
Thread.sleep(1500, 500000); // 1.5 秒 + 500,000 奈秒 (精度視 OS 而定)
// 必須捕獲 InterruptedException
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // 重置中斷標誌
// 處理中斷邏輯
}
class TaskThread extends Thread {
@Override public void run() {
for (int i = 0; i < 10; i++) {
System.out.printf("%s: %d%n", getName(), i);
if (i % 4 == 0) {
try { Thread.sleep(100); } catch (InterruptedException ignored) {}
}
}
}
}
public class SleepDemo {
public static void main(String[] args) {
new TaskThread().start();
}
}
| 特性 | Thread.sleep() | Object.wait() |
|---|---|---|
| 所屬類別 | Thread (靜態) | Object (實例) |
| 釋放鎖 | ❌ **持有鎖不釋放** | ✅ **釋放當前物件鎖** |
| 喚醒方式 | 時間到自動 / interrupt() | notify()/notifyAll() / interrupt() / 時間到 |
| 呼叫前提 | 無 | 必須持有該物件鎖 (在 synchronized 內) |
| 主要用途 | 延遲、定時、讓出 CPU | 線程間協作、條件等待 |
public class SleepLockDemo {
private static final Object LOCK = new Object();
static class Worker extends Thread {
@Override public void run() {
synchronized (LOCK) { // 取得鎖
for (int i = 0; i < 5; i++) {
System.out.printf("%s: %d%n", getName(), i);
if (i % 2 == 0) {
try { Thread.sleep(200); } catch (InterruptedException ignored) {}
}
}
} // 釋放鎖
}
}
public static void main(String[] args) {
new Worker().start(); // Thread-0
new Worker().start(); // Thread-1
// 輸出將完整印完 Thread-0 的 0~4,才輪到 Thread-1
// 證明 sleep 期間鎖未釋放
}
}
Thread-0: 0
Thread-0: 1
Thread-0: 2
Thread-0: 3
Thread-0: 4
Thread-1: 0
Thread-1: 1
Thread-1: 2
Thread-1: 3
Thread-1: 4
wait(timeout) 或釋放鎖後再睡。InterruptedException 後**必須**重置中斷標誌 (Thread.currentThread().interrupt()) 或拋出,否則中斷信號丟失。TimeUnit.MILLISECONDS.sleep(100) (可讀性更好)、ScheduledExecutorService (定時任務)、LockSupport.parkNanos (底層阻塞)。