今天完成了實驗室納新網站的工作,大體功能都已經完善,也和前端測試過了,費了點時間,而且今天大部分時間在看langchain4j的東西,就簡單復習一下八股,等會再復習一下算法題吧
在Java并發編程中,sleep()
和wait()
都用于暫停線程執行,但它們在設計目的、行為和使用場景上有本質區別。以下是詳細對比及示例說明:
核心區別總結
特性 | sleep() | wait() |
---|---|---|
所屬類 | Thread 類的靜態方法 | Object 類的實例方法 |
鎖釋放 | ? 不釋放任何鎖 | ? 釋放對象鎖(只釋放調用它的對象的鎖) |
喚醒條件 | 超時結束或被中斷(InterruptedException ) | 需其他線程調用notify() /notifyAll() 或超時 |
同步要求 | 無需在同步塊中調用 | 必須在synchronized 塊或方法中使用 |
用途 | 單純暫停當前線程 | 線程間通信(協調多個線程的執行順序) |
示例代碼解析
示例1:sleep()
不釋放鎖(獨占鎖場景)
public class SleepDemo {public static void main(String[] args) {Object lock = new Object();new Thread(() -> {synchronized (lock) {System.out.println("Thread-1: 獲得鎖,開始sleep(2000)");try {Thread.sleep(2000); // 暫停2秒,但不會釋放lock鎖} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Thread-1: sleep結束,釋放鎖");}}).start();new Thread(() -> {synchronized (lock) {System.out.println("Thread-2: 獲得鎖"); // 需等待Thread-1釋放鎖}}).start();}
}
輸出結果:
Thread-1: 獲得鎖,開始sleep(2000)
(等待2秒...)
Thread-1: sleep結束,釋放鎖
Thread-2: 獲得鎖
結論:sleep()
期間不釋放鎖,其他線程無法進入同步塊。
示例2:wait()
釋放鎖(線程協作場景)
public class WaitDemo {public static void main(String[] args) throws InterruptedException {Object lock = new Object();// 等待線程new Thread(() -> {synchronized (lock) {System.out.println("Thread-1: 獲得鎖,調用wait()釋放鎖");try {lock.wait(); // 釋放lock鎖,進入等待狀態} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Thread-1: 被喚醒,重新獲得鎖");}}).start();Thread.sleep(500); // 確保Thread-1先執行// 喚醒線程new Thread(() -> {synchronized (lock) {System.out.println("Thread-2: 獲得鎖,執行notify()");lock.notify(); // 喚醒Thread-1(但需退出同步塊才釋放鎖)System.out.println("Thread-2: notify()后,仍持有鎖2秒");try {Thread.sleep(2000); // sleep()不釋放鎖} catch (InterruptedException e) {e.printStackTrace();}}}).start();}
}
輸出結果:
Thread-1: 獲得鎖,調用wait()釋放鎖
Thread-2: 獲得鎖,執行notify()
Thread-2: notify()后,仍持有鎖2秒
(等待2秒...)
Thread-1: 被喚醒,重新獲得鎖
結論:
wait()
立即釋放鎖,Thread-2
得以進入同步塊。Thread-2
調用notify()
后,Thread-1
需等待Thread-2
退出同步塊(釋放鎖)才能重新獲得鎖并繼續執行。
關鍵點詳解
鎖釋放機制:
sleep()
:線程暫停但保留所有鎖,可能導致其他線程阻塞。wait()
:釋放調用對象的鎖,允許其他線程獲得鎖并執行。
喚醒方式:
sleep()
:超時結束或調用線程的interrupt()
方法。wait()
:需其他線程顯式調用notify()
/notifyAll()
,或超時(若設置了超時時間)。
使用約束:
wait()
/notify()
必須在synchronized
代碼塊中調用,否則拋出IllegalMonitorStateException
。sleep()
可在任何上下文調用(但需處理InterruptedException
)。
設計目的:
sleep()
:用于定時任務(如輪詢間隔)、模擬耗時操作。wait()
:用于線程協作(如生產者-消費者模型),避免忙等待(busy-waiting)。
經典應用場景
sleep()
:定時任務調度(如每5秒檢查一次狀態)、模擬網絡延遲。wait()
/notify()
:線程間協調(如生產者生產后通知消費者)、條件等待(等待資源就緒)。
重要提示:Java 5+推薦使用
java.util.concurrent
包的Condition
、CountDownLatch
等高級工具替代wait()
/notify()
,以簡化并發控制。