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

时间:2012-10-09 17:38:07

标签: java multithreading future callable

在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;
    }
}

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

2 个答案:

答案 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。