从正在运行的任务中关闭ExecutorService

时间:2015-04-17 12:14:30

标签: java executorservice scheduledexecutorservice

我正在使用单线程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
            }
        }
    }   
}

shutdown()可以安全shutdownNow()ExecutorService Task.run()吗?如果线程会引发自身中断,那么看起来不对。

在执行Task时发现异常时,我想shutdown service,理想情况下会调用Runner.stopWorking()

我知道我可以使用Callable而让Runner管理重新安排,但我希望保留此结构(Runner将有更多类似的service s ,所以无限循环只是看起来不正确)。

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

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

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

还有其他替代方法吗?

1 个答案:

答案 0 :(得分:3)

  

我可以安全地关闭()或shutdownNow()ExecutorService吗?   Task.run()?如果线程将是一些东西看起来不正确   引发自我中断。

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

是的,线程发出信号终止是完全没问题的。因此,shutdown()执行者可以安全地运行任务。