Java长时间运行的任务线程中断与取消标志

标签 java concurrency multithreading interrupt

我有一个长时间运行的任务,比如:

public void myCancellableTask() {
    while ( someCondition ) {
       checkIfCancelRequested();
       doSomeWork();
    }
 }

任务可以取消(请求取消并且 checkIfCancelRequested() 检查取消标志)。通常,当我像这样编写可取消循环时,我会使用一个标志来指示已请求取消。但是,我知道我也可以使用 Thread.interrupt 并检查线程是否已被中断。我不确定哪种方法是首选方法,为什么,想法?

谢谢,

杰夫

最佳答案

使用中断的一个问题是,如果您不控制所有正在执行的代码,您将面临中断无法“正常”工作的风险,因为其他人对如何中断理解在他们的库中处理中断。那就是 API 不可见地 围绕它处理您变得依赖的中断 导出一个 API。

在您的示例中,假设 doSomeWork 在第 3 方 JAR 中并且看起来像:

public void doSomeWork() {
    try { 
        api.callAndWaitAnswer() ; 
    } 
    catch (InterruptedException e) { throw new AssertionError(); }
}

现在您必须处理 AssertionError(或者您正在使用的库可能抛出的任何其他错误)。我见过有经验的开发人员在接收中断时抛出各种废话!另一方面,也许该方法看起来像这样:

public void doSomeWork() {
    while (true) {
        try { 
            return api.callAndWaitAnswer() ; 
        } 
        catch (InterruptedException e) { /* retry! */ }
    }
}

这种对中断的“不当处理”会导致您的程序无限循环。再一次,不要认为这是荒谬的。那里有很多损坏的中断处理机制。

至少使用你自己的标志对任何第 3 方库来说都是完全不可见的。

关于Java长时间运行的任务线程中断与取消标志,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1914898/

相关文章:

java - 如何从只有 1 个剩余字节的 ByteBuffer 中获取 Int (Java NIO)

java - Android 4.0、4.5 和 5.0 设备的不同布局

c++ - 回调和 `std::recursive_mutex` - 有效用例?

c# - 如何正确使用 ConcurrentQueue 中的 block

java - 如何解决 Java 9 中与分段代码缓存相关的内存问题?

java - NetBeans 7.0.1 : Access to Tomcat server has not been authorized

go - 确保一次仅处理一个请求,并丢弃其他传入的请求

java:用于存储挂起的网络请求的线程安全数据结构(队列+映射)?

java - "Atomically"更新整个数组

c# - 我如何使用带参数的函数在线程中创建什么?