gpt4 book ai didi

java - CompletableFuture 和 CountDownLatch 超时

转载 作者:塔克拉玛干 更新时间:2023-11-01 21:44:04 25 4
gpt4 key购买 nike

我想在 CompletableFuture 中包装一个 Runnable 以进行异步计算,但可以控制计算何时开始和结束。我创建了一个带有 CountDownLatchCompletableFuture 来阻止处理,但以下代码片段会引发错误:

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();

Start Exception in thread "main" java.util.concurrent.TimeoutException at java.util.concurrent.CompletableFuture.timedGet(CompletableFuture.java:1771) at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1915) at Sandbox.main(Sandbox.java:23)

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

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

最佳答案

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

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

事实上,如果您从 get 调用中删除超时(它无限期地阻塞),那么这是系统中死锁的典型示例。工作线程一直等到主线程对闩锁进行倒计时,而主线程等待工作线程完成,以便它可以继续对闩锁进行倒计时。幸运的是,传递给 get 的超时启用了概率死锁避免。相反,您可以随时取消 future 并避免潜在的死锁,只要您的任务对中断有响应即可。

关于java - CompletableFuture 和 CountDownLatch 超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58015472/

25 4 0