| 維度 | Thread.sleep() | Object.wait() |
|---|---|---|
| 所屬類 | Thread (靜態方法) | Object (實例方法) |
| 鎖行為 | 不釋放鎖 | 釋放鎖 |
| 調用前提 | 任意代碼位置 | 必須在 synchronized 塊/方法中 |
| 喚醒方式 | 時間到期 / interrupt() | notify()/notifyAll() / interrupt() / 時間到期 |
| 異常處理 | 必須 catch InterruptedException | 必須 catch InterruptedException |
| 虛假喚醒 | 無 | 可能發生,需循環檢查條件 |
public class SleepHoldLock {
private static final Object LOCK = new Object();
public static void main(String[] args) {
new Thread(() -> {
synchronized (LOCK) {
System.out.println("Thread-A 持有鎖,睡眠 3 秒");
try { Thread.sleep(3000); } catch (InterruptedException ignored) {}
System.out.println("Thread-A 醒來,釋放鎖");
}
}, "Thread-A").start();
// 確保 Thread-A 先獲取鎖
try { Thread.sleep(100); } catch (InterruptedException ignored) {}
new Thread(() -> {
System.out.println("Thread-B 嘗試獲取鎖...");
synchronized (LOCK) {
System.out.println("Thread-B 獲取到鎖"); // 3 秒後才會打印
}
}, "Thread-B").start();
}
}
輸出證明:Thread-B 在 Thread-A sleep 期間無法獲取鎖,處於阻塞狀態。
public class WaitReleaseLock {
private static final Object LOCK = new Object();
public static void main(String[] args) {
new Thread(() -> {
synchronized (LOCK) {
System.out.println("Thread-A 持有鎖,wait 3 秒");
try { LOCK.wait(3000); } catch (InterruptedException ignored) {}
System.out.println("Thread-A 醒來,繼續持有鎖");
}
}, "Thread-A").start();
try { Thread.sleep(100); } catch (InterruptedException ignored) {}
new Thread(() -> {
System.out.println("Thread-B 嘗試獲取鎖...");
synchronized (LOCK) {
System.out.println("Thread-B 立即獲取到鎖"); // 立即打印!
try { Thread.sleep(1000); } catch (InterruptedException ignored) {}
System.out.println("Thread-B 釋放鎖");
}
}, "Thread-B").start();
}
}
輸出證明:Thread-A wait() 釋放鎖,Thread-B 立即獲取鎖 執行。
// 打斷睡眠
Thread t1 = new Thread(() -> {
try { Thread.sleep(10000); } catch (InterruptedException e) {
System.out.println("睡眠被打斷");
return; // 安全退出
}
});
t1.start();
Thread.sleep(100);
t1.interrupt(); // 拋出 InterruptedException
// 打斷等待
Thread t2 = new Thread(() -> {
synchronized (LOCK) {
try { LOCK.wait(10000); } catch (InterruptedException e) {
System.out.println("等待被打斷");
return;
}
}
});
t2.start();
Thread.sleep(100);
t2.interrupt(); // 拋出 InterruptedException
關鍵點:
interrupt() 只設置中斷標誌,不直接拋出異常sleep/wait/join 時檢測到標誌 → 拋出 InterruptedException 並清除標誌interrupt() → 標誌置位,不拋異常,需自行檢查 Thread.interrupted()
// 錯誤:單次 wait,虛假喚醒導致邏輯錯誤
synchronized (lock) {
lock.wait();
doSomething(); // 可能條件未滿足就執行
}
// 正確:循環檢查條件
synchronized (lock) {
while (!condition) {
lock.wait();
}
doSomething(); // 條件確實滿足
}
yield():主動放棄當前時間片,不保證調度結果join():等待目標線程終止,內部調用 wait()Thread.sleep()Object.wait()/notify()LockSupport.park()/unpark()、Condition.await()/signal()、CountDownLatch、CyclicBarrier、CompletableFuture