在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。