【问题标题】:Stop a Background Thread Gracefully [duplicate]优雅地停止后台线程[重复]
【发布时间】:2017-04-11 02:48:18
【问题描述】:

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

我通过将 Runnable 中的所有内容包装在 try catch 块中并捕获 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。

这段代码安全吗,这意味着当调用取消时,它总是保证会杀死线程?

【问题讨论】:

  • 我会更担心进程上下文会在线程处于中间状态时被终止。

标签: java multithreading


【解决方案1】:

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

另一种常见的方法是在 Runnable 中定义一个“正在运行”标志,并在您希望它终止时将其设置为 false。然后,您的 Runnable 可以在其处理过程中方便且安全的位置(例如在其主循环的每次迭代之前)检查此标志。

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

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

【讨论】:

    猜你喜欢
    • 2019-11-10
    • 2011-03-12
    • 2011-04-30
    • 1970-01-01
    • 2011-04-25
    • 1970-01-01
    • 2010-11-05
    • 1970-01-01
    相关资源
    最近更新 更多