英文:
Java BlockingQueue confusion
问题
我正在阅读关于Java BlockingQueue 的内容,许多网站上都提供了一个简单的BlockingQueue实现的示例。代码很简单,但我有点困惑。例如,假设我们填满了队列,然后尝试再次入队3次。这将使3个线程等待。然后当我们调用dequeue时,dequeue方法中的代码将进入第二个if语句,并且会通知所有线程。这是否意味着等待的3个线程都会将节点添加到队列中?这意味着我们将比限制多2个节点吗?我相当确定我在这里误解了一些东西,所以我需要一些简要的解释。
英文:
I am currently reading about Java BlockingQueue and this example is given on many websites for a simple implementation of the BlockingQueue. The code is simple but I am a bit confused. For example lets say we fill up the queue, then we try to enqueue 3 more times. This will make the 3 threads wait. Then when we call dequeue, the code in the dequeue method will enter the second if statement and it will notify all threads. Won't this mean that the 3 threads waiting will all add nodes to the queue? That means we will have 2 more nodes than the limit? I am pretty sure I misunderstood something here so I could use some small explanation.
public class BlockingQueue {
private List queue = new LinkedList();
private int limit = 10;
public BlockingQueue(int limit){
this.limit = limit;
}
public synchronized void enqueue(Object item)
throws InterruptedException {
while(this.queue.size() == this.limit) {
wait();
}
this.queue.add(item);
if(this.queue.size() == 1) {
notifyAll();
}
}
public synchronized Object dequeue()
throws InterruptedException{
while(this.queue.size() == 0){
wait();
}
if(this.queue.size() == this.limit){
notifyAll();
}
return this.queue.remove(0);
}
}
答案1
得分: 1
No, only one will add a node. Notice that your wait
-call in enqueue
is inside a loop:
while(this.queue.size() == this.limit) {
wait();
}
All three threads are notified but only one thread can be in the synchronized
-block. The first thread to enter the block adds a node, so the queue is full again. The other both threads enter the block (one after another) but see the queue being full again, which will put them right into waiting state again as that's the loop-condition.
You can imagine a wait
to be an exit and entrance point of a synchronized
-block. When a thread enters wait
, then the corresponding lock is released. A thread that has been waiting in a wait
and is notified, is trying to acquire the corresponding lock for the critical section again and blocks if it is currently in use. So only one of the notified three threads can enter at a time.
英文:
No, only one will add a node. Notice that your wait
-call in enqueue
is inside a loop:
while(this.queue.size() == this.limit) {
wait();
}
All three threads are notified but only one thread can be in the synchronized
-block. The first thread to enter the block adds a node, so the queue is full again. The other both threads enter the block (one after another) but see the queue being full again, which will put them right into waiting state again as that's the loop-condition.
You can imagine a wait
to be an exit and entrace point of a synchronized
-block. When a thread enters wait
, then the corresponding lock is released. A thread that has been waiting in a wait
and is notified, is trying to acquire the corresponding lock for the critical section again and blocks if it is currently in use. So only one of the notified three threads can enter at a time.
答案2
得分: 1
请注意,来自.enqueue()
的wait()
位于循环内部。任何被唤醒的线程都将重新检查许可以添加元素,由于一次只有一个线程可以执行同步方法,所以不会有问题 - 一个线程有幸插入一个元素,其他线程在失败的重新检查后继续等待。
英文:
Note that wait()
from .enqueue()
is inside loop. Any awoken thread will re-check permit to add an element and since only single thread can execute synchronized method at a time, there will be no problem - one thread gets lucky to insert an element, others continue to wait after failed re-check.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论