在Java中,多線程的等待喚醒機制是一種非常重要的同步機制,它可以讓線程之間相互協作,確保多個線程能夠正確地共享資源,避免數據不一致和線程沖突等問題。
等待喚醒機制主要包括兩個操作:等待(wait)和喚醒(notify)。在Java中,這兩個操作都是由Object類提供的,因此任何Java對象都支持等待喚醒機制。
一、等待操作
等待操作是通過調用對象的wait()方法實現的。當一個線程調用對象的wait()方法時,該線程會被放入到對象的等待集中,并釋放對象的鎖。其他線程可以獲取對象的鎖并執行相關操作。
在調用wait()方法時,必須先獲取對象的鎖。否則,會拋出IllegalMonitorStateException異常。通常,在調用wait()方法之前,需要先通過synchronized塊或方法來獲取對象的鎖。
二、喚醒操作
喚醒操作是通過調用對象的notify()方法或notifyAll()方法實現的。當一個線程調用對象的notify()方法時,會從對象的等待集中選擇一個線程喚醒,讓其獲取對象的鎖并執行相關操作。如果調用notifyAll()方法,則會將對象等待集中的所有線程都喚醒。
同樣地,在調用notify()或notifyAll()方法之前,也需要先獲取對象的鎖。否則,會拋出IllegalMonitorStateException異常。
三、示例代碼
演示:
public class WaitWakeExample {
private Object lock = new Object();
private int count = 0;
public void incrementCount() {
synchronized (lock) {
while (count == 5) {
try {
// 等待喚醒
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
count++;
System.out.println("Count: " + count);
// 喚醒其他線程
lock.notifyAll();
}
}
public void decrementCount() {
synchronized (lock) {
while (count > 0) {
try {
// 等待喚醒
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
count--;
System.out.println("Count: " + count);
// 喚醒其他線程
lock.notifyAll();
}
}
}
incrementCount()和decrementCount()這兩個方法都會先檢查count的值,如果count不滿足條件,就會調用wait()方法進入等待狀態。當count滿足條件時,就會調用notifyAll()方法喚醒所有等待的線程。這樣就可以保證多個線程能夠正確地共享count變量,避免數據不一致和線程沖突等問題。