1

为什么在调用 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();
  }
}
4

1 回答 1

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

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

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

于 2013-03-04T19:07:24.987 回答