【发布时间】: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