【问题标题】:Shutting down an ExecutorService from running task从正在运行的任务中关闭 ExecutorService
【发布时间】:2015-06-24 06:56:11
【问题描述】:

我使用单线程ScheduledExecutorService 来处理一些Runnable 任务。当我的Runnable 完成工作后,它会在ScheduledExecutorService 中以可变延迟重新安排自己的时间。这种情况会无限期地发生,直到Runnable 捕获Exception

public class Runner { 

    ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();

    public void startWorking() { 
        // Single-shot start
        service.submit(new Task(service));
    }

    public void stopWorking() { 
        service.shutDown();
        // Do some other stuff
    }

    private static final class Task implements Runnable { 
        ScheduledExecutorService service;
        private Task(ScheduledExecutorService service) {
            this.service = service;
        }
        @Override 
        public void run() { 
            try { 
                // Do some work...
                service.schedule(this, variableDelay, TimeUnit.SECONDS);
            }
            catch(SomethingHappenedException e){ 
                // Shutdown service
            }
        }
    }   
}

我可以从Task.run() 安全地从shutdown()shutdownNow()ExecutorService 吗?如果线程将引发对自身的中断,则某些情况看起来不正确。

当执行Task时捕获到异常时,我想shutdownservice,最好调用Runner.stopWorking()

我知道我可以改用Callable 并让Runner 管理重新安排,但我想保留这个结构(Runner 将有更多类似的services,所以无限循环只是没有'不要看那里)。

我想我可以使用对 Runner 的引用来继承 ScheduledThreadPoolExecutor 以覆盖 afterExecute 并在那里处理关机。

public class Runner { 
    ScheduledExecutorService service = new ScheduledThreadPoolExecutor(1){
      protected void afterExecute(Runnable r, Throwable t) { 
        if (t != null) { 
            Runner.this.stopWorking();
        }
    };
    // ...
}

我对这种方法的担忧是,如果运行Task 的线程调用afterExecute,这将与从Task.run() 本身调用shutDown() 具有相同的效果。

还有其他替代方法吗?

【问题讨论】:

  • 看起来从任务本身调用shutdown() 甚至shutdownNow() 是安全的,并且可以正常工作。如果确实如此,那么这个问题的答案就是微不足道的。

标签: java executorservice scheduledexecutorservice


【解决方案1】:

我可以安全地关闭()或关闭现在() ExecutorService 任务运行()?如果线程将是某些东西看起来不正确 引起自己的中断。

shutdown() 不会中断已经运行的任务,但会阻止新任务的提交。 shutdownNow() 也不会中断正在运行的任务,而是向所有工作人员发出“信号”,他们应该被终止。取决于Thread 的实现(或者更确切地说是Runnable 本身)它是否尊重这样的信号(我记得Thread.isTerminated())。

是的,线程发出信号终止自己是完全可以的。所以shutdown() executor 运行任务是安全的。

【讨论】:

    猜你喜欢
    • 2012-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-31
    • 2019-11-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多