优雅地停止后台线程

时间:2017-04-10 18:39:22

标签: java multithreading

我的任务是实现后台线程来执行后端异步处理,在某些情况下需要外部停止作业。

我通过在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时,它总能保证杀死线程吗?

1 个答案:

答案 0 :(得分:1)

这种方法可能没问题,只要您的Runnable与之合作,并且Runnable执行的工作可以随时安全地中断,而不会导致数据不一致等问题。

另一种常见的方法是定义一个"运行"在Runnable中标记,并在需要终止时将其设置为false。然后,您的Runnable可以在其处理中的方便和安全点检查此标志(例如在其主循环的每次迭代之前)。

这种方法可能不会立即终止任务,但它可以确保终止干净并且没有损坏。

这些方法中的任何一种都需要您的Runnable的合作 - 通常没有合作就无法安全可靠地终止Java线程。