如何中断在 take() 上阻塞的 BlockingQueue?
我有一个类,它从 BlockingQueue
获取对象,并通过在连续循环中调用 take()
来处理它们。 在某些时候我知道不会有更多的对象被添加到队列中。 如何中断 take()
方法以使其停止阻塞?
这是处理对象的类:
public class MyObjHandler implements Runnable {
private final BlockingQueue<MyObj> queue;
public class MyObjHandler(BlockingQueue queue) {
this.queue = queue;
}
public void run() {
try {
while (true) {
MyObj obj = queue.take();
// process obj here
// ...
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
这是使用此类处理对象的方法:
public void testHandler() {
BlockingQueue<MyObj> queue = new ArrayBlockingQueue<MyObj>(100);
MyObjectHandler handler = new MyObjectHandler(queue);
new Thread(handler).start();
// get objects for handler to process
for (Iterator<MyObj> i = getMyObjIterator(); i.hasNext(); ) {
queue.put(i.next());
}
// what code should go here to tell the handler
// to stop waiting for more objects?
}
I have a class that takes objects from a BlockingQueue
and processes them by calling take()
in a continuous loop. At some point I know that no more objects will be added to the queue. How do I interrupt the take()
method so that it stops blocking?
Here's the class that processes the objects:
public class MyObjHandler implements Runnable {
private final BlockingQueue<MyObj> queue;
public class MyObjHandler(BlockingQueue queue) {
this.queue = queue;
}
public void run() {
try {
while (true) {
MyObj obj = queue.take();
// process obj here
// ...
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
And here's the method that uses this class to process objects:
public void testHandler() {
BlockingQueue<MyObj> queue = new ArrayBlockingQueue<MyObj>(100);
MyObjectHandler handler = new MyObjectHandler(queue);
new Thread(handler).start();
// get objects for handler to process
for (Iterator<MyObj> i = getMyObjIterator(); i.hasNext(); ) {
queue.put(i.next());
}
// what code should go here to tell the handler
// to stop waiting for more objects?
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
如果中断线程不是一种选择,另一种方法是在队列上放置一个“标记”或“命令”对象,该对象将被 MyObjHandler 识别并跳出循环。
If interrupting the thread is not an option, another is to place a "marker" or "command" object on the queue that would be recognized as such by MyObjHandler and break out of the loop.
但是,如果这样做,线程可能会被中断,而队列中仍有项目等待处理。 您可能需要考虑使用
poll
而不是take
,这将允许处理线程在等待一段时间后超时并终止没有新的输入。However, if you do this, the thread might be interrupted while there are still items in the queue, waiting to be processed. You might want to consider using
poll
instead oftake
, which will allow the processing thread to timeout and terminate when it has waited for a while with no new input.很晚了,但希望这对其他人也有帮助,因为我遇到了类似的问题并使用了埃里克森上面进行了一些细微的更改,
这解决了这两个问题
BlockingQueue
以便它知道不必等待更多元素Very late but Hope this helps other too as I faced the similar problem and used the
poll
approach suggested by erickson above with some minor changes,This solved both the problems
BlockingQueue
so that it knows it has not to wait more for elements中断线程:
Interrupt the thread:
或者不要打断,这很讨厌。
Or don't interrupt, its nasty.
queue.notify()
, if it ends, callqueue.done()