關于 sleep 和 wait 深度對比!
在計算機編程中,特別是在多線程或并發編程中,sleep 和 wait 是兩個非常常見的函數,但它們有不同的用途和工作機制,這篇文章我們將詳細地討論 sleep 和 wait 的區別,包括它們的內部工作原理、應用場景以及詳細的示例代碼,以幫助更全面地理解它們。
sleep
工作機制:
- 暫停當前線程: sleep 方法暫停當前執行的線程一段指定的時間,時間結束后線程再恢復執行。
- 不會釋放鎖: 即使線程在 sleep 狀態下持有鎖,它也不會釋放。它依然占用著該鎖,其他線程無法獲得該鎖。
- 線程狀態轉換: sleep 方法會使線程從運行(RUNNING)狀態轉換為計時等待(TIMED_WAITING)狀態。
- 靜態方法: 它是 Thread 類的靜態方法,調用時通過 Thread.sleep 訪問。
應用場景:
- 限流: 控制任務執行的頻率,防止線程過度占用CPU資源。
- 定時任務: 在某個循環中,定時執行某些任務。
示例代碼:
public class SleepExample extends Thread {
public void run() {
try {
System.out.println("Thread going to sleep for 2 seconds.");
Thread.sleep(2000); // 睡眠 2 秒
System.out.println("Thread woke up after sleeping.");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
SleepExample thread = new SleepExample();
thread.start();
}
}
wait
工作機制:
- 釋放鎖并等待通知: wait 方法使當前線程等待,直到其他線程調用當前對象的 notify 或 notifyAll 方法。調用 wait 時,線程會釋放它持有的鎖。
- 必須在同步塊或同步方法中使用: wait 方法必須在同步塊或同步方法中調用,否則會拋出 IllegalMonitorStateException。
- 線程狀態轉換: wait 方法會使線程從運行(RUNNING)狀態轉換為等待(WAITING)狀態。
- 對象方法: 它是 Object 類的方法,所以任何對象都可以調用。
應用場景:
- 線程間通信: 多個線程協同工作時,一個線程等待某個條件滿足后,再被其他線程通知繼續執行。
- 生產者-消費者模型: 經常用于實現生產者-消費者模式中的同步。
示例代碼:
public class WaitNotifyExample {
private static final Object lock = new Object();
public static void main(String[] args) throws InterruptedException {
// 等待線程
Thread waitingThread = new Thread(() -> {
synchronized (lock) {
try {
System.out.println("Thread waiting for the lock to be released.");
lock.wait(); // 進入等待狀態并釋放鎖
System.out.println("Thread resumed after lock released.");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
// 通知線程
Thread notifyingThread = new Thread(() -> {
synchronized (lock) {
System.out.println("Notifying other threads.");
lock.notify(); // 通知其他等待該鎖的線程
System.out.println("Notified waiting thread.");
}
});
waitingThread.start();
Thread.sleep(1000); // 確保 waitingThread 先持有鎖并進入等待狀態
notifyingThread.start();
}
}
sleep 和 wait的對比
特性 | sleep | wait |
釋放鎖 | 否 | 是 |
需要在同步塊或方法中 | 否 | 是 |
屬于 | Thread 類 | Object 類 |
引發異常 | InterruptedException | InterruptedException 引發機制相同 |
作用范圍 | 當前調用的線程 | 當前擁有鎖的線程 |
線程狀態改變 | 變為計時等待(TIMED_WAITING) | 變為等待(WAITING) |
典型應用場景 | 暫停線程的一段時間,用于控制節奏或定時操作 | 線程間通信,生產者-消費者模型等 |
總結
本文,我們分析了sleep 和 wait,sleep用于暫停當前線程一段指定時間,但仍保持鎖,這常用來控制執行節奏或定時操作。wait使線程釋放鎖并進入等待狀態,直到通過 notify/notifyAll 被喚醒,需在同步塊中使用,適用于線程間通信如生產者-消費者模型。