【问题标题】:Java - stopping all tasks in ExecutorServiceJava - 停止 ExecutorService 中的所有任务
【发布时间】:2012-11-30 09:53:13
【问题描述】:

我有一些执行器服务来安排本地任务,例如读取文件、连接到数据库等。这些进程执行大量日志记录,这是基于有许多线程同时运行、编写自己的东西的事实而广泛使用的进入日志。

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

更新: 这是一些代码

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);
}

【问题讨论】:

  • 如果您不介意,请给我们一些代码。任何机会记录都是异步完成的?您是否使用shutdown 而不是shutdownNow?原因有很多。
  • 关闭服务并取消任务并不意味着这些任务会立即停止。

标签: java concurrency executorservice


【解决方案1】:

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

来检查自己

Thread.currentThread().isInterrupted()

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

【讨论】:

    【解决方案2】:

    当你 shutdownNow 你的执行者或调用 cancel(true) 时(顺便说一下 shutdownNow 已经取消了已经提交的任务,所以你的循环是不必要的)你的任务会被中断。

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

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

    例如,如果您的任务运行 while(true) 循环,您可以将其替换为:

    while(!Thread.currentThread().isInterrupted()) {
        //your code here
    }
    cleanup();
    //and exit
    

    另一个例子:

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

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

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

    【讨论】:

    • @Bober02 在你的任务中,你需要定期检查线程是否被中断——当你检测到中断时,必要时清理并退出任务。
    • 我不明白这个问题。我正在向 Executor 服务提交一个任务,该服务内部存储所有线程。我所能做的就是使用 API 来关闭它。我在监控哪些线程?
    • @Bober02 我添加了一些您的 Runnables(任务)可能是什么样子的示例 - 我希望现在更清楚了。
    【解决方案3】:

    Executors 支持 2 种关闭方式

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

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

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

    【讨论】:

    • 不完全是 - shutdownNow 不会“强制”关闭任务,它只是中断它们,这可能会也可能不会停止。
    • 同意@assylias。将编辑我的帖子以纳入您的评论。谢谢。
    • 所以有什么办法可以“强制”关闭任务...?
    • 你为什么要强制喊叫?这不是一个好主意,这就是 Java 不提供任何直接方法的原因。 (停止/暂停已弃用)
    • 仍然是迄今为止我找到的最佳答案。现在按预期工作。再次感谢
    【解决方案4】:

    - 尝试使用shutdowNow() 方法,它会关闭所有由这个Executor 启动的任务抛出InterruptedException,但是IOSynchronized operation 不能被中断.

    例如:

    ExecutorService executor = Executors.newFixedThreadPool();
    
    executor.execute();
    
    ...
    ...
    
    executor.shutdownNow();
    

    - cancel(true) 方法可以与submit() 方法一起使用来关闭特定任务。

    【讨论】:

    • 这是不正确的 - shutdownNow 不会关闭任务,它会中断它们,这可能会或不会关闭它们。
    猜你喜欢
    • 2013-12-01
    • 2011-06-24
    • 1970-01-01
    • 1970-01-01
    • 2011-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多