Java - 停止ExecutorService中的所有任务

Bob*_*r02 6 java concurrency executorservice

我有一些执行器服务来安排本地任务,如读取文件,连接到数据库等.这些进程执行大量的日志记录,这是基于有许多线程并发运行的事实,将自己的东西写入日志.

现在,在某个时间点可以引发异常,该异常到达捕获所有异常的主要方法.然后我关闭所有服务并取消每个任务,希望阻止所有进一步的消息到日志.不幸的是,在关闭所有内容之后,这些消息仍然显示出来......有什么想法吗?

更新:这是一些代码

public class Scheduler{

private final ExecutorService service;
private final ConcurrentMap<Object, Future<V>> cache;

...

public void shutDown() {
    service.shutdownNow();
    for (Future task : cache.values())
        task.cancel(true);
}
Run Code Online (Sandbox Code Playgroud)

pil*_*rth 7

任务将继续运行,直到它到达检测到线程已被中断的点.调用某些系统或线程函数时可能会发生这种情况,并且可能会抛出异常.在您的情况下,您可能需要通过致电来检查自己

Thread.currentThread().isInterrupted()

如果您的代码运行循环并且您希望以这种方式停止,那么这样做是个好主意.


rai*_*mar 5

执行器支持两种关闭方式

shutdown():启动有序关闭,执行先前提交的任务,但不会接受新任务。如果已经关闭,调用不会产生额外的效果。

shutdownNow():尝试停止所有正在执行的任务,停止正在等待的任务的处理,并返回正在等待执行的任务的列表。除了尽最大努力尝试停止处理主动执行的任务之外,没有任何保证。

参考: http: //docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ExecutorService.html#shutdownNow()

  • 不完全是 - shutdownNow 不会“强制”关闭任务,它只是中断它们,这可能会或可能不会停止它们。 (7认同)

ass*_*ias 5

当你shutdownNow的执行者或电话cancel(true)(顺便说一下shutdownNow已经取消已经提交的任务,所以你的循环是不必要的)时,你的任务就会被打断.

根据他们对中断的反应,他们可能会:

  • 立即停止他们正在做的事
  • 一段时间后停止他们正在做的事情,因为没有经常检查中断信号
  • 继续做他们正在做的事情因为中断信号被忽略了

例如,如果您的任务运行while(true)循环,则可以使用以下内容替换它:

while(!Thread.currentThread().isInterrupted()) {
    //your code here
}
cleanup();
//and exit
Run Code Online (Sandbox Code Playgroud)

另一个例子:

for (int i = 0; i < aBigNumber; i++) {
    if (Thread.currentThread().isInterrupted()) { break; }
    //rest of the code for the loop
}
cleanup();
//and exit
Run Code Online (Sandbox Code Playgroud)

另一个例子,如果你调用一个抛出InterruptedException的方法:

try {
    Thread.sleep(forever); //or some blocking IO or file reading...
} catch (InterruptedException e) {
    cleanup();
    Thread.currentThread.interrupt();
    //and exit
}
Run Code Online (Sandbox Code Playgroud)