Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java executorService.shutdownNow()不';不要停止线程_Java_Multithreading_Scheduledexecutorservice - Fatal编程技术网

Java executorService.shutdownNow()不';不要停止线程

Java executorService.shutdownNow()不';不要停止线程,java,multithreading,scheduledexecutorservice,Java,Multithreading,Scheduledexecutorservice,我有一个计划执行器服务设置,如 class Test { private final ScheduledExecutorService executor; public Test() { executor = Executors.newSingleThreadScheduledExecutor((runnable) -> { Thread thread = new Thread(runnable, this.getClass().ge

我有一个计划执行器服务设置,如

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中:


除了尽最大努力尝试停止处理积极执行的任务之外,没有其他保证。例如,典型的实现将通过Thread.interrupt取消,因此任何未能响应中断的任务可能永远不会终止

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

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

scheduleWithFixedDelay()的javadoc中:

如果任务的任何执行遇到异常,则会抑制后续执行否则,任务将仅通过取消或终止执行者而终止。

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


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

默认情况下,此类已取消的任务不会自动从工作队列中删除,直到其延迟消失。虽然这可以进行进一步的检查和监视,但也可能会导致取消任务的无限保留。要避免这种情况,请将setRemoveOnCancelPolicy设置为true,这将导致在取消任务时立即从工作队列中删除任务

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

解决方案:

  • 在提交计划之前执行
    executor.setRemoveOnCancelPolicy(true)
[编辑]: 由于使用工厂方法,因此无法直接实现

进行以下更改:

  • 私有最终调度线程池执行器执行器
  • executor=newscheduledthreadpoolexecutor(1,(runnable)->{

“除了尽最大努力停止处理正在执行的任务外,没有其他保证。例如,典型的实现将通过Thread.interrupt()取消,因此任何无法响应中断的任务可能永远不会终止。”-同样来自:你等待终止60秒。你知道refreshdata平均需要多长时间吗?你使用的是什么版本的Java?@JohnVint我使用的是Java 1.8。Refresh做了很多事情,但通常只需要不到60秒。这一点很好。因为我在服务器和本地运行此代码。rem上的代码这台机器似乎更经常出故障