Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/354.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 当阻塞队列变为空时,如何阻止提供程序?_Java_Concurrency_Blockingqueue - Fatal编程技术网

Java 当阻塞队列变为空时,如何阻止提供程序?

Java 当阻塞队列变为空时,如何阻止提供程序?,java,concurrency,blockingqueue,Java,Concurrency,Blockingqueue,通常,我希望阻塞阻塞队列的提供者,直到队列变为空,然后将一批元素放入队列中 我在这里发现了一个相对的问题: 但是我还是很困惑 我当前的实现类似于(伪代码): BlockingQueue BlockingQueue=new BlockingQueue(); //提供者代码 while(true){ //等待阻塞队列变为空 已同步(阻止队列){ 而(!blockingQueue.isEmpty()){ blockingQueue.wait(); } } //将一批元素放入阻塞队列 List ele

通常,我希望阻塞阻塞队列的提供者,直到队列变为空,然后将一批元素放入队列中

我在这里发现了一个相对的问题:

但是我还是很困惑

我当前的实现类似于(伪代码):

BlockingQueue BlockingQueue=new BlockingQueue();
//提供者代码
while(true){
//等待阻塞队列变为空
已同步(阻止队列){
而(!blockingQueue.isEmpty()){
blockingQueue.wait();
}
}
//将一批元素放入阻塞队列
List elementList=getSomeElements();
for(元素:元素列表){
blockingQueue.put(元素)
}
}
//消费者代码
while(true){
//采取措施
blockingQueue.take();
//如果阻塞队列变为空,请通知提供程序
已同步(阻止队列){
if(blockingQueue.isEmpty()){
blockingQueue.notify();
}
}
}
代码似乎还可以,但我仍然怀疑它不是线程安全的,并且可能导致死锁情况


我的实现是线程安全的吗?有更好的方法吗?

此代码不是线程安全的。您正在等待
synchronized
块中的某个条件,但在采取操作之前离开
synchronized
块。当您离开
synchronized
块时,无法保证该条件保持为真。除此之外,名称“
blockingQueue
”表明您混合了两种不同的同步机制。这是造成死锁的一个方法,正如您已经链接的问答中所解释的那样。@Holger是的,我同意代码不是线程安全的。但这会导致僵局吗?代码片段与中的代码稍有不同。死锁只应在提供程序等待永远不会出现的通知时发生。我仍然不明白如何达到这种状态。通过将阻塞操作移出
synchronized
块,您破坏了线程安全。通过将阻塞操作移动到
synchronized
块中将其恢复,将使其再次陷入死锁。无论哪种情况,混合不同的同步机制都会导致问题。此代码不是线程安全的。您正在等待
synchronized
块中的某个条件,但在采取操作之前离开
synchronized
块。当您离开
synchronized
块时,无法保证该条件保持为真。除此之外,名称“
blockingQueue
”表明您混合了两种不同的同步机制。这是造成死锁的一个方法,正如您已经链接的问答中所解释的那样。@Holger是的,我同意代码不是线程安全的。但这会导致僵局吗?代码片段与中的代码稍有不同。死锁只应在提供程序等待永远不会出现的通知时发生。我仍然不明白如何达到这种状态。通过将阻塞操作移出
synchronized
块,您破坏了线程安全。通过将阻塞操作移动到
synchronized
块中将其恢复,将使其再次陷入死锁。在这两种情况下,混合不同的同步机制都会导致问题。