我正在使用单线程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()
的效果相同本身。
还有其他替代方法吗?
答案 0 :(得分:3)
我可以安全地关闭()或shutdownNow()ExecutorService吗? Task.run()?如果线程将是一些东西看起来不正确 引发自我中断。
shutdown()
不会中断已经运行的任务,但会阻止新任务被提交。
shutdownNow()
也不会中断正在运行的任务,但会“通知”所有工作人员应该终止它们。它是Thread
实现(或者更确切地说是Runnable
本身)它是否会尊重这样的信号(我记得Thread.isTerminated()
)。
是的,线程发出信号终止是完全没问题的。因此,shutdown()
执行者可以安全地运行任务。