【问题标题】:Why set the interrupt bit in a Callable为什么在 Callable 中设置中断位
【发布时间】:2013-02-19 00:21:21
【问题描述】:

因此,此资源 (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?

【问题讨论】:

    标签: java interrupt future callable interrupted-exception


    【解决方案1】:

    中断线程应该会终止它,但比kill() 更脆弱。只有在各种阻塞操作期间才会检查线程的中断状态。

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

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

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

    【讨论】:

      【解决方案2】:

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

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

      注意,在这种情况下,您仍然不会直接从Future.get() 获得 InterruptedException。因为它是由 callable 抛出的,所以它将被包裹在 ExecutionException 中(这样您就可以区分 callable 的中断和主线程的中断)。

      【讨论】:

        猜你喜欢
        • 2018-12-10
        • 1970-01-01
        • 2020-06-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-10-26
        • 2015-08-26
        • 1970-01-01
        相关资源
        最近更新 更多