[英]Shutting down an ExecutorService from running task
I'm using a single threaded ScheduledExecutorService
in order to process some Runnable
tasks. 我正在使用单线程ScheduledExecutorService
来处理一些Runnable
任务。 When my Runnable
has finished its work, it reschedules itself in the ScheduledExecutorService
with a variable delay. 当我的Runnable
完成其工作时,它会在ScheduledExecutorService
重新安排自己的变量延迟。 This happens indefinitely until the Runnable
catches an Exception
. 这种情况无限期地发生,直到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
}
}
}
}
Can I shutdown()
or shutdownNow()
the ExecutorService
safely from Task.run()
? 我可以从Task.run()
安全地shutdown()
或shutdownNow()
ExecutorService
吗? Something doesn't look right if the thread will be provoking an interrupt to itself. 如果线程会激发对自身的中断,那么看起来不对。
When an exception is caught while executing Task
, I'd like to shutdown
the service
, ideally calling Runner.stopWorking()
. 当执行Task
捕获到异常时,我想shutdown
该service
,理想情况下调用Runner.stopWorking()
。
I know I could use a Callable
instead and let Runner
manage reschedulings, but I'd like to keep this structure ( Runner
will have more analogous service
s, so an infinite loop just doesn't look right there). 我知道我可以使用Callable
而让Runner
管理重新安排,但我想保留这个结构( Runner
将有更多类似的service
,所以无限循环只是看起来不正确)。
I guess I could subclass ScheduledThreadPoolExecutor
to override afterExecute
and handle shutdown there, using a reference to Runner
. 我想我可以afterExecute
ScheduledThreadPoolExecutor
以使用对Runner
的引用来覆盖afterExecute
并在那里处理shutdown。
public class Runner {
ScheduledExecutorService service = new ScheduledThreadPoolExecutor(1){
protected void afterExecute(Runnable r, Throwable t) {
if (t != null) {
Runner.this.stopWorking();
}
};
// ...
}
My concern with this approach is, if afterExecute
will be invoked by the thread that ran the Task
, this would have the same effects as calling shutDown()
from Task.run()
itself. 我对这种方法的关注是,如果运行Task
的线程调用afterExecute
,这将与从Task.run()
本身调用shutDown()
具有相同的效果。
Is there any other alternative approach to this? 还有其他替代方法吗?
Can I shutdown() or shutdownNow() the ExecutorService safely from Task.run()? 我可以从Task.run()安全地关闭()或shutdownNow()ExecutorService吗? Something doesn't look right if the thread will be provoking an interrupt to itself. 如果线程会激发对自身的中断,那么看起来不对。
shutdown()
will not interrupt already running tasks but will prevent new task from beeing submited. shutdown()
不会中断已经运行的任务,但会阻止新任务被提交。 shutdownNow()
doesn't interrupt running tasks either, but "signals" all workers that they should be terminated. shutdownNow()
也不会中断正在运行的任务,但会“通知”所有工作人员应该终止它们。 It is up to Thread
implementation (or rather Runnable
itself) will it honor such signal ( Thread.isTerminated()
as I remember) or not. 它取决于Thread
实现(或者更确切地说是Runnable
本身)它是否会尊重这样的信号(我记得的Thread.isTerminated()
)。
And yes, it is perfectly fine for thread to signal itself to be terminated. 是的,线程发出信号终止是完全没问题的。 So it is safe to shutdown()
executor from running task. 因此, shutdown()
执行器从运行任务中是安全的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.