gpt4 book ai didi

java - executorService.shutdownNow() 不会停止线程

转载 作者:行者123 更新时间:2023-11-30 02:50:28 27 4
gpt4 key购买 nike

我有一个预定的执行程序服务设置,例如

class Test {
private final ScheduledExecutorService executor;
public Test() {
executor = Executors.newSingleThreadScheduledExecutor((runnable) -> {
Thread thread = new Thread(runnable, this.getClass().getName());
thread.setDaemon(true);
return thread;
});
executor.scheduleWithFixedDelay(
new TestRefreshTask(), 0, 50000, TimeUnit.MILLISECONDS
);
}

private class TestRefreshTask implements Runnable {
@Override
public void run() {
//refresh some data
refreshdata();
}
}

public void close() {
executor.shutdown();
try {
if(!executor.awaitTermination(60, TimeUnit.SECONDS)) {
executor.shutdownNow();
executor.awaitTermination(60, TimeUnit.SECONDS));
}
} catch (InterruptedException e) {
//Retry to dispose task
executor.shutdownNow();
Thread.currentThread().interrupt();
throw new RuntimeException(e);
}
}
}

为了停止该线程,我调用 close 方法,但该线程通常不会停止。我不确定出了什么问题,以及是否应该以某种方式处理 run() 代码中的 InterruptedException。

最佳答案

  • 线下的真正解决方案。这部分仅描述陷阱。

来自 shutdownNow() 的 javadoc:

There are no guarantees beyond best-effort attempts to stop processing actively executing tasks. For example, typical implementations will cancel via Thread.interrupt, so any task that fails to respond to interrupts may never terminate.

根据经验,线程确实会被中断,但根据本文档,即使这样也不能保证。

但是,您的任务不是您自己控制的,它是在 scheduleWithFixedDelay() 中创建的私有(private)任务。

来自scheduleWithFixedDelay()的javadoc:

If any execution of the task encounters an exception, subsequent executions are suppressed. Otherwise, the task will only terminate via cancellation or termination of the executor.

这意味着 shutdownNow() 不会停止线程。取消部分对我来说有点不清楚,因为与 Future 相反,Runnable 没有 cancel() 方法。任务停止的另一个原因是执行程序的终止,但是池仅在任务停止时终止。

<小时/>

真正的解决方案隐藏在ScheduledThreadPoolExecutor的javadoc中的这部分:

By default, such a cancelled task is not automatically removed from the work queue until its delay elapses. While this enables further inspection and monitoring, it may also cause unbounded retention of cancelled tasks. To avoid this, set setRemoveOnCancelPolicy to true, which causes tasks to be immediately removed from the work queue at time of cancellation.

当您命令执行程序停止时,它会设置中断标志,如果它是 ScheduledThreadPoolExecutor,则在 removeOnCancelPolicy 为 true 时删除任务。

解决方案:

  • 在提交计划之前执行executor.setRemoveOnCancelPolicy(true)

[编辑]:由于您使用工厂方法,因此无法直接实现。

进行以下更改:

  • 私有(private)最终 ScheduledThreadPoolExecutor 执行器;
  • executor = new ScheduledThreadPoolExecutor(1, (可运行) -> {

关于java - executorService.shutdownNow() 不会停止线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38826985/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com