Java - 停止 ExecutorService 中的所有任务

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13642723/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 13:28:55  来源:igfitidea点击:

Java - stopping all tasks in ExecutorService

javaconcurrencyexecutorservice

提问by Bober02

I have a few executor services which schedule local tasks such as reading a file, connecting to db etc. These processes do huge amount of logging, which is extensive based on the fact there are many threads running concurrently, writing their own thing into the log.

我有一些执行程序服务来安排本地任务,例如读取文件、连接到 db 等。这些进程进行了大量的日志记录,基于有许多线程并发运行,将自己的事情写入日志的事实,这是广泛的.

Now, at some point in time an exception can be raised, which reaches the main method where all exceptions are caught. I am then shutting down all the services and cancelling each task, hoping to prevent all further messages to the log. Unfortunately, the messages are still showing up after I shut everything down... Any ideas?

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

UPDATE: Here is some code

更新:这是一些代码

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

回答by pillingworth

The task will carry on running until it reaches a point where it detects the Thread has been interrupted. This can happen when calling some System or Thread functions and you may get an exception thrown. In your case you probably need to check yourself by calling

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

Thread.currentThread().isInterrupted()

Thread.currentThread().isInterrupted()

It is a good idea to do this if your code runs loops and you are expecting to be stopped in this way.

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

回答by assylias

When you shutdownNowyour executor or call cancel(true)(by the way shutdownNowalready cancels the already submitted tasks so your loop is unnecessary) your tasks get interrupted.

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

Depending on how they react to the interruption, they might then:

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

  • stop what they are doing immediately
  • stop what they are doing after a while, because the interruption signal is not being checked regularly enough
  • continue doing what they are doing because the interruption signal has been ignored
  • 立即停止他们正在做的事情
  • 一段时间后停止他们正在做的事情,因为中断信号没有得到足够的定期检查
  • 继续做他们正在做的事情,因为中断信号已被忽略

For example, if your tasks run a while(true)loop, you can replace it with something like:

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

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

Another example:

另一个例子:

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

Another example, if you call a method that throws InterruptedException:

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

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

回答by rai.skumar

Executors support 2 approaches of shutdown

Executors 支持 2 种关闭方式

shutdown(): Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be accepted. Invocation has no additional effect if already shut down.

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

shutdownNow(): Attempts to stop all actively executing tasks, halts the processing of waiting tasks, and returns a list of the tasks that were awaiting execution. There are no guarantees beyond best-effort attempts to stop processing actively executing tasks.

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

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

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

回答by Kumar Vivek Mitra

-Try using the shutdowNow()method, it will shutdown all the task started by this Executor throwing InterruptedException, but IOand Synchronized operationcan't be interrupted.

-尝试使用shutdowNow()方法,它会关闭所有的任务此执行投掷开始InterruptedException,但IOSynchronized operation不能中断。

Eg:

例如:

ExecutorService executor = Executors.newFixedThreadPool();

executor.execute();

...
...

executor.shutdownNow();

-cancel(true)method can be used with submit()method to shutdown a particular task.

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