我有一个BlockingQueue,它在单个后台线程上处理工作事件。各种线程调用add将一些工作添加到队列中,而单个后台线程调用take获取工作并逐个处理它们。最终可能是停止处理工作的时间,我想确保请求工作的调用者要么获得他们的结果,要么获得null,表示他们的工作未完成,因为BlockingQueue正在关闭。
如何干净地停止接受新工作,我能想到的最好方法是将BlockingQueue字段设置为null,然后在调用add时捕获NullPointerException。在将字段设置为null之前,我将保留指针的本地副本,以便在停止接受工作后将其排空。我认为这会起作用,但似乎有点hacky,有没有适当的方法来做到这一点?
以下是代码的样子:
如何干净地停止接受新工作,我能想到的最好方法是将BlockingQueue字段设置为null,然后在调用add时捕获NullPointerException。在将字段设置为null之前,我将保留指针的本地副本,以便在停止接受工作后将其排空。我认为这会起作用,但似乎有点hacky,有没有适当的方法来做到这一点?
以下是代码的样子:
ArrayBlockingQueue<Command> commandQueue =
new ArrayBlockingQueue<Command>(100, true);
public boolean addToQueue(Command command) {
try {
return commandQueue.add(command);
} catch (IllegalStateException e) {
return false;
}
}
@Override
public void run() {
try {
while (!Thread.currentThread().isInterrupted()) {
Command command = commandQueue.take();
// ... work happens here
// result is sent back to caller
command.provideResponseData(response);
}
} catch (InterruptedException e) {
// Break out of the loop and stop
}
// TODO: stop accepting any new work, drain the queue of existing work
// and provide null responses
}