小编典典

为什么在Callable中设置中断位

java

因此,该资源(http://www.ibm.com/developerworks/java/library/j-jtp05236/index.html)建议在该线程不处理中断本身时将其设置为“
这样,调用堆栈中更高级别的代码就可以了解中断并在需要时对其进行响应 。”

假设我正在使用ExecutorService在其他线程中运行某些内容。我构造一个Callable并将此Callable传递到ExecutorService.submit()中,该方法返回一个Future。如果Callable被中断,然后重置中断位,则在调用Future.get()时,关联的Future将不会引发InterruptedException。因此,如果此Future是主线程访问已生成线程的唯一方法,那么在Callable中设置中断位的目的是什么。

class MyCallable implements Callable<String> {
  @Override
  public String call() {
    while (!Thread.currentThread().isInterrupted()) {
    }
    Thread.currentThread().interrupt();
    return "blah";
  }
}

 ExecutorService pool = makeService();
 Future<String> future = pool.submit(new MyCallable());
 // Callable gets interrupted and the Callable resets the interrupt bit.
 future.get(); // Does not thrown an InterruptedException, so how will I ever know that the Callable was interrupted?

阅读 321

收藏
2020-11-30

共1个答案

小编典典

您是正确的,在这种情况下,不会在两个线程之间传递中断标志(这是出于任何原因设计内置ExecutorService的方式)。如果希望主线程看到可调用对象的中断状态,则必须从调用方法中抛出InterruptedException。

class MyCallable implements Callable<String> {
  @Override
  public String call() {
    // ...
    if(Thread.currentThread().isInterrupted()) {
      throw new InterruptedException();
    }
    return "blah";
  }
}

注意,Future.get()在这种情况下,您仍然不会直接从InterruptedException中获取。由于它是由可调用对象抛出的,因此它将被包装在中ExecutionException(这样您就可以区分可调用对象的中断和主线程的中断)。

2020-11-30