关于ExecutorService
和关机过程,我有几个问题。
我的用例:
我使用ExecutorService
生成固定数量的线程,其运行方法如下所示:
while (true) {
try {
this.currentThreadRunning = true;
processMessage();
}
catch (Throwable e) {
// Keeping the thread alive despite exceptions.
}
}
这些线程无限运行,轮询消息。
我想做什么? 我正在轮询SQS队列以获取消息并进行处理。
显然,在我的情况下,ExecutorService's
关闭方法不起作用。调用shutdownNow()
时,我的所有线程都会被毫不客气地关闭。我讨厌它!
有没有办法调用awaitTermination
并在我的Runnable
实例中(在finally块中?)验证是否已启动shutdown并为当前线程触发相同的操作?
更新:我重构了我的代码以执行轮询,然后生成线程来处理它们。因此,Runnable实例的run方法不必是无限循环。并且awaiTermination
将导致线程的明确关闭。可以肯定的是,我在shutdownNow
之后触发了awaitTermination
。
答案 0 :(得分:0)
为了无限运行Runnables
我依赖于抓取InterruptedException
,这通常会从我的通话shutdownNow()
或偶尔通过调用Future#cancel(true)
while(!Thread.interrupted()) {
try {
} catch(InterruptedException e) {
break;
} catch(Throwable e) {
// Keeping the thread alive despite exception
}
}
// Thread was interrupted via shutdownNow(), cleanup resources
如果我需要区分可恢复中断和关闭中断,那么我在AtomicBoolean doShutdown
中共享Runnables
,其初始化为false
并设置为true
我想要一个InterruptedException
来终止线程。
答案 1 :(得分:0)
您必须检查正在运行的线程的中断状态(请参阅此处有关中断的教程:https://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html)。你的代码应该是:
while (!Thread.currentThread().isInterrupted()) {
try {
this.currentThreadRunning = true;
processMessage();
}
catch (Throwable e) {
// Keeping the thread alive despite exceptions.
}
}
但请注意,您必须在从runnable调用的代码中正确处理中断。如果有以下内容:
try {
// do something
} catch(InterruptedException e) {
// ignore
}
然后这不起作用。处理InterruptedException
的正确方法是致电Thread.currentThread().interrupt();
。
答案 2 :(得分:0)
我认为你所做的事情在概念上是错误的。
awaitTermination
意味着等待所有线程自然完成然后停止执行程序。提交Runnable
时,它不应该知道它的执行情况,因此,将runnable连接到执行程序并不是一个好主意恕我直言。
也许您应该查看Future
课程并将Runnable
实施移到那里。然后,您将被迫实施一个您可能觉得有用的cancel(boolean)
方法。
您的用例是什么?也许如果您解释一下,社区可以指出更适合的实施。
答案 3 :(得分:0)
您不应该致电shutdownNow()
但是您应该只拨打关机并使用awaitTermination
等待一段时间。
所以关机会是这样的
声明一个易变变量
private volatile stopThread = false;
关机时你打电话
this.stopThread = true;
executor.shutdown();
executor.awaitTermination(..
executor.shutdownNow() // in case termination takes too long
在线程中检查stopThread变量。你不能在这里使用isInterrupted,因为我们没有打断线程。我们只是在等待线程根据这个条件退出
if(stopThread){
// calling off all the operations and returning
}
我写了一篇关于正确地将执行器服务放下来的文章 http://programtalk.com/java/executorservice-not-shutting-down/ 我希望这会对你有所帮助。