我最近看到下面的實現排隊的一個BlockingQueue的 (source)while循環在Java中的BlockingQueue實現
public synchronized void enqueue(Object item)
throws InterruptedException {
while(this.queue.size() == this.limit) {
wait();
}
if(this.queue.size() == 0) {
notifyAll();
}
this.queue.add(item);
}
爲什麼while
循環必要的,並且可以在while
通過if (this.queue.size() == this.limit)
被替換看起來方法入隊是同步的,因此一次只能有一個線程在方法體中執行,並調用wait()
。線程一旦收到通知,無法再繼續檢查this.queue.size() == this.limit
條件繼續前進嗎?
謝謝。後續問題:爲什麼在添加項目之前排隊調用notifyAll()?這不會導致線程等待出隊以檢查空隊列嗎?首先添加項目然後notifyAll會更好嗎?像這樣:queue.add(item); if(queue.size()== 1){notifyAll();} – morfys 2012-03-26 08:43:04
恕我直言,關閉add(item)和notifyAll()的順序並不重要,因爲方法enqueue是同步的。因此add(item)和notifyAll()調用都必須在另一個線程可以執行之前完成。 – morfys 2012-03-26 09:06:21