【问题标题】:setting interrupt bit does not make Future.get() throw TimeoutException设置中断位不会使 Future.get() 抛出 TimeoutException
【发布时间】:2013-03-04 18:53:31
【问题描述】:

为什么在调用 Future.get() 时不设置 Callable 中的中断位会导致代表 Callable 的 Future 抛出 TimeoutException?

public class ExecutorServiceTest extends MockitoTestCase {
  private static CountDownLatch latch1 = new CountDownLatch(1);

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

  void testInterrupt() throws Exception {
    ExecutorService pool = Executors.newFixedThreadPool(numThreads);
    Future<String> future = pool.submit(new TaskChecksForInterruptedExcAndDoesSetInterruptedBit());
    latch1.await(); // Don't interrupt the Callable until it actually starts processing
    pool.shutdownNow();
    try {
      future.get(100, TimeUnit.MILLISECONDS);
    } catch (final TimeoutException e) {
      // Why doesn't this get called!
      return;
    }
    fail();
  }
}

【问题讨论】:

    标签: java timeout interrupt future timeoutexception


    【解决方案1】:
    1. shutdownNow() 调用尝试中断所有正在运行的任务。在这种情况下,在您的繁忙循环中检测到中断,因此代码继续并且 Callable 返回“blah”(而不是异常)

    2. 根据规范,只有当线程等待完整的超时时间但没有结果可用时才会抛出 TimeoutException。中断不适合这种情况。

    3. 您对 CountDownLatch 的使用不正确。你递减它,但我看不到对latch1.await()的调用

    【讨论】:

    • 顺便说一下,我修复了 CountDownLatch。
    • 那么Future.get()什么时候返回TimeoutException呢?只有当 Callable 没有按指定的超时长度返回时?我刚刚想到的其他事情,既然设置了生成的线程的中断位,为什么 Future.get() 不会抛出 InterruptedException?
    • 是的,future.get(..) 中的 TimeoutException 仅在完全超时期限过去时发生。 future.get() 可以抛出 InterruptedException 的唯一情况是当 get(..) 上阻塞的线程被另一个线程中断时。它与运行您的可调用对象的后台线程的状态无关。
    • 好的。我不知道以某种方式调用 Future.get() 是否会检查后台线程是否已被中断,并在这种情况下抛出 InterruptedException。我想它没有。
    • future.get() 也可以抛出其他类型的异常。如果后台线程因异常而终止,那么您将得到一个包装原始异常的 ExecutionException。
    猜你喜欢
    • 2020-10-06
    • 1970-01-01
    • 1970-01-01
    • 2015-10-11
    • 1970-01-01
    • 2021-10-12
    • 2016-11-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多