Chi*_*may 0 java multithreading
我为Prod-Cons问题编写了一个简单的阻塞队列示例.以下示例不起作用; 除非我在等待线程上使用notify交换enqueue/dequeue逻辑的add/remove部分.在BlockingQueue的任何实现中,我都找不到任何关于此行为的明确解释.在enqueue部分,添加元素然后通知不应该是正确的吗?通过这种方式,我可以保证当Consumer线程运行时,它应该有一个元素给消费者,并且不会返回null.请解释.
import java.util.LinkedList;
import java.util.Queue;
public class BlockingQueueCustom<T> {
private int size = 10;
private Queue<T> queue = new LinkedList<T>();
public BlockingQueueCustom(int s) {
this.size = s;
}
public synchronized void enqueue(T element) throws InterruptedException {
while (queue.size() == size) {
wait();
}
queue.add(element); //Comment this part to make it work
if (queue.size() == 0) {
this.notifyAll();
}
//queue.add(element); Uncommenting this will make it work
}
public synchronized T dequeue() throws InterruptedException {
while (queue.size() == 0) {
this.wait();
}
T element = queue.remove(); //Comment this part to make it work
if (queue.size() == size) {
this.notifyAll();
}
return element; //Comment this part to make it work
//return queue.remove(); Uncommenting this will make it work
}
}
Run Code Online (Sandbox Code Playgroud)
在enqueue部分,添加元素然后通知不应该是正确的吗?
那部分并不重要,因为你处于同步方法中 - 其他线程在你离开enqueue方法之前不会运行.但是,它在测试方面确实很重要size().看这里:
if (queue.size() == 0)
Run Code Online (Sandbox Code Playgroud)
如果你刚添加一个元素,你怎么期望这是真的?您可以检查它是否为1,这意味着在添加元素之前它必须为0.或者您可以保留一个单独的变量:
boolean shouldNotify = queue.size() == 0;
queue.add(element);
if (shouldNotify) {
this.notifyAll();
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
138 次 |
| 最近记录: |