在Callable中处理Thread.interrupted()的正确方法



在Callable中处理Thread.interrupted()的正确方法是什么?我猜测可调用程序应该抛出一个InterruptedException;例如:

public class MyCallable implements Callable<Object> {
public Object call() {
Object result = null;
// Simulate long-running operation that calculates result
while (true) {
...
if (Thread.interrupted()) {
throw new InterruptedException();
}
}
result = ... // something produced by the long-running operation    
return result;
}
}

这是正确的,还是有更合适的方法来处理它?谢谢

编辑

经过一番反复之后,你似乎希望能够中断你的IO例程。对于某些NIOInterrutibleChannel类来说,这似乎是一项不错的工作。例如,从以下BufferedReader读取是可中断的,并将抛出InterruptedIOException。有关NIO代码的更多示例,请参阅此处。

BufferedReader in = new BufferedReader(new InputStreamReader(
Channels.newInputStream((new FileInputStream(
new File(...))).getChannel())));

然后,您可以调用future.cancel(),这将中断您的线程并导致IO抛出InterruptedIOException。如果发生这种情况,您可以而不是捕获IOException,并让它从call()方法中慢慢流出。


如果你想把call()方法被中断的消息传给Future,那么我认为抛出InterruptedException是可以的。另一种选择是只使用return null;call()方法中的其他标记对象。如果线程被中断,我通常会这样做。

需要记住的一件事是,如果call()抛出InterruptedException,那么当您执行future.get()时,它将抛出ExecutionException,并且该异常的原因将是InterruptedException。不要混淆,如果get(long timeout, TimeUnit unit)超时,future.get()本身也可以抛出InterruptedException

try {
result = future.get();
} catch (ExecutionException e) {
if (e.getCause() instanceof InterruptedException) {
// call() method was interrupted
}
} catch (InterruptedException e) {
// get was interrupted
}

然而,如果调用了future.cancel(true),则future.get()将抛出一个CancellationException

这实际上取决于线程在get()上等待的方式。如果不希望等待线程抛出异常,则不希望throw new InterruptedException

想象一下

try{
future.get();
}catch(ExecutionException ex){
}catch(InterruptedException em){
}

如果出现任何异常,您希望它是什么?在您的情况下,它是ExecutionException。如果不需要ExecutionException,则不应重新引发InterruptedException。

相关内容

  • 没有找到相关文章

最新更新