在Callable中处理Thread.interrupted()的正确方法是什么?我猜测callable应该抛出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;
}
}
这是正确的,还是有更合适的方法来处理它?感谢。
答案 0 :(得分:6)
修改强>:
经过一些来回,看起来你想要能够中断你的IO例程。这似乎是一些NIO InterrutibleChannel
类的好工作。例如,从以下BufferedReader
中读取是可中断的,并将抛出InterruptedIOException
。请参阅此处more examples of the NIO code。
BufferedReader in = new BufferedReader(new InputStreamReader(
Channels.newInputStream((new FileInputStream(
new File(...))).getChannel())));
然后,您可以调用future.cancel()
来中断您的线程并导致IO抛出InterruptedIOException
。如果发生这种情况,您可以不抓住IOException
并让它从call()
方法中流出。
如果您想要回传Future
call()
方法被中断,那么我认为投掷InterruptedException
就可以了。另一种选择是仅使用return null;
方法中的call()
或其他标记对象。这通常是我在线程被中断时所做的事情。
要记住的一件事是,如果call()
抛出InterruptedException
,当您执行future.get()
时,它会抛出ExecutionException
而原因该异常将成为InterruptedException
。如果future.get()
超时,InterruptedException
也可以抛出get(long timeout, TimeUnit unit)
,请不要感到困惑。
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
。
答案 1 :(得分:1)
实际上,这取决于您希望线程在get()
上等待的方式。如果您不希望等待的线程抛出异常,那么您不希望throw new InterruptedException
想象
try{
future.get();
}catch(ExecutionException ex){
}catch(InterruptedException em){
}
如果发生任何异常,您会期望它是什么?在您的情况下,它是ExecutionException
。如果您不想要ExecutionException
,则不应重新抛出InterruptedException。