【问题标题】:Timeout with CompletableFuture and CountDownLatchCompletableFuture 和 CountDownLatch 超时
【发布时间】:2019-09-19 16:37:18
【问题描述】:

我想将Runnable 包装在CompletableFuture 中以进行异步计算,但可以控制计算何时开始和结束。我用CountDownLatch 创建了一个CompletableFuture 来阻止处理,但是下面的sn-p 会抛出一个错误:

CountDownLatch countDownLatch = new CountDownLatch(1);
CompletableFuture completableFuture = CompletableFuture.runAsync(() -> {
    try {
        countDownLatch.await();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println("Stop");
});
Thread.sleep(1000L);
System.out.println("Start");
completableFuture.get(1000L, TimeUnit.MILLISECONDS);
countDownLatch.countDown();

开始 线程“主”java.util.concurrent.TimeoutException 中的异常 在 java.util.concurrent.CompletableFuture.timedGet(CompletableFuture.java:1771) 在 java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1915) 在 Sandbox.main(Sandbox.java:23)

另一方面,当我在没有超时的情况下调用 get 时,它会冻结(仅打印 Start)。

我希望 CompletableFuture 中的可运行对象在调用 countDownLatch.countDown(); 时运行。

【问题讨论】:

  • completableFuture.get(1000L, TimeUnit.MILLISECONDS); - 你阻塞了 1000 毫秒,在你得到 TimeoutException 之后,主线程没有机会到达 countDownLatch.countDown()
  • @Eugene 继续阅读 - 没有超时 Stop 也永远不会打印
  • 当然不是——甚至没有达到该代码。在countDownLatch.await(); 周围再添加两个Syso 语句

标签: java multithreading concurrency java-8 completable-future


【解决方案1】:

因为CompletableFuture#get 是一个阻塞调用。所以,countDownLatch.countDown(); 直到CompletableFuture#get 得到结果时才会执行。 CompletableFuture 不会完成并返回结果,因为它将等待 countDownLatch 倒计时。所以,基本上你已经在 2 个线程之间创建了一个依赖关系,这样一个线程将等待另一个线程,反之亦然。

【讨论】:

    【解决方案2】:

    您正在等待超时到期,而不允许线程继续进行。 Future.get 是阻塞的,这将永远不允许您在超时到期之前countDown Latch,因此您的线程永远不会完成。您在这里要做的是,首先,通过在Latch 上调用countDown 让线程继续,然后在get 调用中等待超时。只需反转两条线即可解决问题。这是它的外观。

    countDownLatch.countDown();
    completableFuture.get(1000L, TimeUnit.MILLISECONDS);
    

    实际上,如果您从 get 调用中删除超时(它会无限期地阻塞),那么这就是系统中死锁的典型示例。工作线程一直等待,直到主线程倒计时锁存器,而主线程等待工作线程完成,以便它可以继续并倒计时锁存器。幸运的是,超时时间可以避免概率死锁。相反,您可以随时cancelfuture 并避免潜在的死锁,只要您的任务响应中断。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-05-14
      • 1970-01-01
      • 2012-05-06
      • 1970-01-01
      • 1970-01-01
      • 2014-06-27
      • 1970-01-01
      • 2021-02-20
      相关资源
      最近更新 更多