Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/400.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 以可调用的方式处理Thread.interrupted()的正确方法?_Java_Multithreading_Future_Callable - Fatal编程技术网

Java 以可调用的方式处理Thread.interrupted()的正确方法?

Java 以可调用的方式处理Thread.interrupted()的正确方法?,java,multithreading,future,callable,Java,Multithreading,Future,Callable,在可调用函数中处理Thread.interrupted()的正确方法是什么?我猜callable应该抛出InterruptedException;例如: public class MyCallable implements Callable<Object> { public Object call() { Object result = null; // Simulate long-running operation that calcula

在可调用函数中处理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;
    }
}
公共类MyCallable实现可调用{
公共对象调用(){
对象结果=空;
//模拟计算结果的长期运行操作
while(true){
...
if(Thread.interrupted()){
抛出新的InterruptedException();
}
}
result=…//由长时间运行的操作生成的内容
返回结果;
}
}
这是正确的,还是有更合适的处理方法?谢谢。

编辑

经过一些来回,似乎你想能够中断你的IO例程。对于某些NIO
InterrutibleChannel
类来说,这似乎是一项很好的工作。例如,从以下
BufferedReader
读取是可中断的,并将抛出
InterruptedIOException
。请看这里

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


如果您想将
调用()
方法被中断的情况传回
未来
,那么我认为抛出
InterruptedException
是可以的。另一种选择是只
返回nullcall()
方法中的code>或其他标记对象。如果线程被中断,我通常会这样做

需要记住的一件事是,如果
call()
抛出
InterruptedException
,当您执行
future.get()
时,它将抛出一个
ExecutionException
,而该异常的原因将是
InterruptedException
。如果
get(长超时,时间单位)
超时,则
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()
。如果不希望等待线程抛出异常,则不希望
抛出新的InterruptedException

想象

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

}catch(InterruptedException em){

}

如果发生任何异常,您会期望它是什么?在您的情况下,它是一个
执行异常
。如果您不希望出现
执行异常
,则不应重新显示InterruptedException。

我将提供更多的上下文。我的代码实际上没有使用while(true)循环-它是从一个定制的InputStream中读取,该InputStream检查read(byte)中Thread.interrupted()的值。read()方法抛出InterruptedException以确保调用代码(从流中读取)正确关闭流。结果表明,这不起作用,因为read()只能抛出IOException。看起来我想要的可能是中断异常。当然@Greg。另一个想法是使用NIO支持的
interruptbleChannel
。我曾考虑过使用interruptbleChannel,但现在还不清楚该怎么做(我的代码使用标准的java.io输入/输出流)。只是为了结束循环-我的最终解决方案是实现一个自定义InputStream类,该类封装另一个InputStream并在read()中调用Thread.currentThread().isInterrupted()。如果isInterrupted()返回true,则该方法抛出InterruptedIOException。否则,它会将read()委托给包装流。它还将close()委托给包装流。我对OutputStream也做了同样的操作。在本例中,我的callable是从InputStream读取的。如果在未来实例上调用cancel(),我希望确保流关闭(请参阅我对Gray答案的评论)。您是否曾经在未来调用过get
?是的,最终我将在未来调用get()(如果未来未被取消)。好的,如果InterruptedException在
调用
方法之外抛出,任何后续的
get
都将看到InterruptedException,在我看来,它似乎不适合等待线程。这还假设线程池线程将清理可调用的资源。如果等待的线程将清理资源,那么获取InterruptedException可能是有意义的。@灰色如果取消导致InterruptedException,其中未来基本上被取消,则似乎在
ExecutionException
之前抛出了
取消异常
,这是一个真正的解释源代码
InterruptedException
是。我之前读过,但它没有提到可调用。不过这篇文章很好。
try{
  future.get();
}catch(ExecutionException ex){

}catch(InterruptedException em){

}