我有一个长时间运行的任务,比如:
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/