首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java sleep() 與 wait() 區別總結:鎖行為、喚醒方式、使用場景對比

     編輯:Java 相關知識

核心差異速查表

維度Thread.sleep()Object.wait()
所屬類Thread (靜態方法)Object (實例方法)
鎖行為不釋放 當前持有的對象鎖釋放 當前對象鎖,進入等待集
喚醒方式時間到自動喚醒需 notify()/notifyAll() 喚醒 (或中斷/超時)
調用前提無必須持有該對象鎖 (在 synchronized 內)
拋出異常InterruptedExceptionInterruptedException
典型用途定時延遲、輪詢間隔線程協作、生產者消費者

代碼演示:wait/notify 協作 vs sleep 獨立運行


public class WaitVsSleep {
    static final Object LOCK = new Object();

    public static void main(String[] args) {
        new Thread(() -> {
            synchronized (LOCK) {
                System.out.println("T1: 進入同步塊,調用 wait() 釋放鎖");
                try { LOCK.wait(); } catch (InterruptedException ignored) {}
                System.out.println("T1: 被喚醒,繼續持有鎖執行");
            }
        }, "T1").start();

        try { Thread.sleep(1000); } catch (InterruptedException ignored) {}

        new Thread(() -> {
            synchronized (LOCK) {
                System.out.println("T2: 獲得鎖,調用 notify() 喚醒 T1");
                LOCK.notify();
                System.out.println("T2: 睡眠 2s (持有鎖),T1 必須等待");
                try { Thread.sleep(2000); } catch (InterruptedException ignored) {}
                System.out.println("T2: 釋放鎖");
            }
        }, "T2").start();
    }
}
/* 輸出順序:
T1: 進入同步塊,調用 wait() 釋放鎖
T2: 獲得鎖,調用 notify() 喚醒 T1
T2: 睡眠 2s (持有鎖),T1 必須等待
T2: 釋放鎖
T1: 被喚醒,繼續持有鎖執行
*/

關鍵觀察

  • wait() 釋放鎖 → T2 能進入同步塊 → notify() 將 T1 從等待集移至入口集 → T1 仍需等待 T2 釋放鎖 (退出 synchronized) 才能繼續。
  • sleep() 不釋放鎖 → 若 T2 在 synchronized 內 sleep,T1 無法進入。
  • 若註釋 LOCK.notify(),T1 永久等待 (程序掛起)。

進階:wait(long timeout) 超時機制


synchronized (obj) {
    obj.wait(5000); // 5秒後自動喚醒 (若未被 notify)
    // 醒來後需重新檢查條件 (spurious wakeup 防禦)
}

最佳實踐

  1. 同步塊內使用 wait/notify 實現線程協作 (生產者消費者、線程池任務隊列)。
  2. 單純延遲、輪詢間隔用 Thread.sleep 或 TimeUnit.MILLISECONDS.sleep。
  3. 永遠在循環中調用 wait():while (conditionNotMet) obj.wait(); 防止虛假喚醒。
  4. 優先使用 java.util.concurrent 高級組件 (BlockingQueue, CountDownLatch, Semaphore, Condition) 替代底層 wait/notify。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved