0

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

假设我正在使用 ExecutorService 在不同的线程中运行某些东西。我构造了一个 Callable 并将这个 Callable 传递给 ExecutorService.submit(),它返回一个 Future。如果 Callable 被中断然后重置中断位,则关联的 Future 在调用 Future.get() 时不会抛出 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?
4

2 回答 2

1

在这种情况下,没有在 2 个线程之间传递中断标志是正确的(无论出于何种原因,这就是内置 ExecutorService 的设计方式)。如果您希望主线程看到可调用的中断状态,那么您必须从您的调用方法中抛出 InterruptedException。

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

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

于 2013-03-04T19:47:01.153 回答
0

中断线程应该会终止它,但方式比kill(). 仅在各种阻塞操作期间检查线程的中断状态。

如果您的线程在这些操作之一期间被中断,InterruptedException则会抛出 an 。发生这种情况时,您希望尽快干净地退出。那么,Callable如果executor服务线程中断了怎么办呢?

如果它的操作很短,一个有效的选择是正常完成该操作,但在线程上设置中断状态,以便执行器服务将在此操作完成后关闭。

如果操作较长,您可能希望抛出一个异常,告诉调用者该操作已中断。

于 2013-03-04T20:30:51.107 回答