我的任务是实现后台线程来执行后端异步处理,在某些情况下需要外部停止作业。
我通过在try catch块中包装Runnable中的所有内容并捕获InterruptionException来实现它,如果捕获线程将只返回并退出。
Runnable task = () -> {
try {
while (true) {
// do stuff
// sleep for interval
Thread.sleep(this.checkInterval);
}
} catch (InterruptedException ex) {
// cleanup and exit
return; // exit thread
} catch (Exception ex) {
// cleanup and exit
return; // exit thread
}
};
我正在使用ExecutorService SingleThreadExecutor并提交如下的作业。
this.job = executorService.submit(task);
然后我使用
停止线程boolean canceled = this.job.cancel(true);
似乎工作正常,因为如果线程正在运行,取消会导致InterruptionException。
这段代码是否安全,这意味着当调用cancel时,它总能保证杀死线程吗?
答案 0 :(得分:1)
这种方法可能没问题,只要您的Runnable与之合作,并且Runnable执行的工作可以随时安全地中断,而不会导致数据不一致等问题。
另一种常见的方法是定义一个"运行"在Runnable中标记,并在需要终止时将其设置为false
。然后,您的Runnable可以在其处理中的方便和安全点检查此标志(例如在其主循环的每次迭代之前)。
这种方法可能不会立即终止任务,但它可以确保终止干净并且没有损坏。
这些方法中的任何一种都需要您的Runnable的合作 - 通常没有合作就无法安全可靠地终止Java线程。