notifyAll()
是 Java 中 Object
類的一個方法,用于喚醒在此對象監視器上等待的所有線程。在并發編程中,notifyAll()
的使用需要遵循一些最佳實踐以確保代碼的正確性和效率。
notifyAll()
:在調用 notifyAll()
之前,確保當前線程持有對象的監視器鎖。這可以通過在同步塊或同步方法中調用 notifyAll()
來實現。synchronized (lock) {
// ...
lock.notifyAll();
}
java.util.concurrent.locks.Condition
而不是 wait()
和 notifyAll()
。Condition
提供了更高級的功能,如能夠更好地處理多個條件和公平性。Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
// 等待
lock.lock();
try {
while (/* condition not met */) {
condition.await();
}
} finally {
lock.unlock();
}
// 通知
lock.lock();
try {
// ...
condition.signalAll();
} finally {
lock.unlock();
}
避免使用 notify()
:notify()
只喚醒一個線程,這可能導致其他線程無法得到喚醒。在大多數情況下,使用 notifyAll()
更安全,因為它可以確保所有等待的線程都有機會繼續執行。
始終在循環中檢查條件:在調用 wait()
或 await()
之前,始終在循環中檢查條件是否滿足。這是因為線程可能在條件滿足之前被喚醒,這種情況稱為“虛假喚醒”。
synchronized (lock) {
while (/* condition not met */) {
lock.wait();
}
// ...
}
避免過度同步:盡量減少同步代碼塊的大小,以減少線程之間的競爭。只在訪問共享資源時才進行同步,并盡快退出同步塊。
使用高級并發工具:Java 提供了許多高級并發工具,如 ExecutorService
、Semaphore
、CountDownLatch
等。在可能的情況下,使用這些工具而不是手動管理線程和同步。
遵循這些最佳實踐可以幫助您編寫更健壯、更高效的并發代碼。