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

Gre*_*own 7 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Gra*_*ray 6

编辑:

经过一些来回,看起来你想要能够中断你的IO例程.这似乎是一些NIO InterrutibleChannel课程的好工作.例如,从以下内容中读取BufferedReader是可中断的并将抛出InterruptedIOException.有关NIO代码的更多示例,请参见此处.

BufferedReader in = new BufferedReader(new InputStreamReader(
    Channels.newInputStream((new FileInputStream(
        new File(...))).getChannel())));
Run Code Online (Sandbox Code Playgroud)

然后,你可以调用future.cancel()哪个会中断你的线程并导致IO抛出一个InterruptedIOException.如果发生这种情况,你就无法抓住IOException并让它从call()方法中流出.


如果你想传回Future那个call()方法被打断的那么我觉得投掷InterruptedException很好.另一种选择是使用return null;您的call()方法中的just 或其他标记对象.这通常是我在线程被中断时所做的事情.

要记住的一件事是,如果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
 }
Run Code Online (Sandbox Code Playgroud)

但是,如果future.cancel(true)被召唤,那么future.get()意志就会抛出CancellationException.