![](/img/trans.png)
[英]Why the ArrayBlockingQueue is called a bounded queue while a LinkedBlockingQueue is called an unbounded blocking queue?
[英]Java ArrayBlockingQueue blocking until the queue has something in it
我有许多不同的套接字连接到我的代码,每个套接字都在独立线程上侦听。 在将对象传递到这些套接字中的任何一个之前,时间可能会过去。 所以我有一个基本上永远运行的 while(running) 循环。
然后为了同步所有不同的线程,我有一个 ArrayBlockingQueue。 每当套接字/线程组合接收到一个对象时,我就会将该对象添加到 ArrayBlockingQueue(因为它会自动为我同步)。 然后在 while(running) 代码中,我删除对象并处理它。
问题是处理器在那个 while(running) 循环中变得疯狂......理想情况下,我想阻止开始处理所有对象,直到 ArrayBlockingQueue 实际上有一些东西要处理,希望处理器不会继续运行。
你知道这是否可能?
这是我当前的代码,它导致处理器旋转并浪费周期......
@Override
public void run()
{
while(running)
{
while(messageQueue.size() > 0)
{
Object o = messageQueue.remove();
}
}
}
这是我想要的...
@Override
public void run()
{
while(running)
{
messageQueue.BlockUntilSomethingInHere();
while(messageQueue.size() > 0)
{
Object o = messageQueue.remove();
}
}
}
请注意,在执行messageQueue.remove()
之前检查messageQueue.size() > 0
被称为check-then-act反模式。 如果您有多个线程移除元素,则有可能条件在检查和后续操作之间发生变化,从而导致异常。
只需使用take()
而不是remove()
:
while(running) try {
Object o = messageQueue.take();
// ...
} catch(InterruptedException ex) {
// (running) will be checked before the next loop iteration
}
take()
将等待元素变为可用。 要在队列为空时结束此循环,您必须将running
设置为false
并中断线程。 如果无法中断,您可以使用定时等待:
while(running) try {
Object o = messageQueue.poll(1, TimeUnit.SECOND);
if(o != null) {
// ...
}
}
catch(InterruptedException ex) {
// (running) will be checked before the next loop iteration
}
然后,可能需要一秒钟,直到等待空队列的线程对running
设置为false
做出反应(请注意将running
声明为volatile
)。 可以更改超时时间,以权衡响应能力和 CPU 消耗。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.