8

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

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

4

2 回答 2

7

编辑

经过一番来回之后,您似乎希望能够中断您的 IO 例程。InterrutibleChannel对于某些 NIO类来说,这似乎是一项不错的工作。例如,从以下内容读取BufferedReader是可中断的并且会抛出InterruptedIOException. 有关NIO 代码的更多示例,请参见此处。

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

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


如果您想传回Futurecall()方法被中断的情况,那么我认为投掷InterruptedException很好。另一种选择是仅使用您的方法中return null;的其他标记对象或其他标记对象。call()如果线程被中断,这通常是我所做的。

要记住的一件事是,如果call()抛出InterruptedException,当您执行 a 时,future.get()它会抛出 aExecutionException并且该异常的原因将是 a 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()则将改为抛出 a CancellationException

于 2012-10-09T17:40:36.517 回答
1

这实际上取决于您希望线程如何等待get()。如果您希望等待线程抛出异常,那么您不希望throw new InterruptedException

想象

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

}catch(InterruptedException em){

}

如果发生任何异常,您希望它是什么?在你的情况下,它是一个ExecutionException. 如果你不想要一个ExecutionException那么你不应该重新抛出 InterruptedException。

于 2012-10-09T17:46:32.877 回答