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
块中将其恢复,将使其再次陷入死锁。在这两种情况下,混合不同的同步机制都会导致问题。