gpt4 book ai didi

java - CompletableFuture 未在超时时完成

转载 作者:行者123 更新时间:2023-12-02 08:57:15 32 4
gpt4 key购买 nike

我有一个从输入流读取的方法read。如果超时后 read 尚未完成,我想完成 future 。

public static void main(String[] args) {
CompletableFuture<?> future = new CompletableFuture<>();
future
.thenRunAsync(() -> {
try {
read(data);
} catch (IOException e) {
future.completeExceptionally(e);
}
})
.orTimeout(1, TimeUnit.SECONDS);

future.join();
}

但是当我运行此代码时,它不会因超时而完成,并且无论如何都会等待输入流。

最佳答案

您的代码至少存在两个问题:

  1. 没有执行任何操作。您创建一个 CompletableFuture,然后对其调用 thenRunAsyncthenRunAsync 创建的阶段仅在上一个阶段完成后才会触发。由于您从未完成原始的CompletableFuture,因此这种情况永远不会发生。您最终也会加入一个永远不会完成的 future 。

  2. 您加入了错误的 CompletableFuturethenRunAsyncorTimeout 等方法返回一个新实例,它创建了一种阶段“链”。每个阶段都是由其“父”阶段的完成触发的。为了充分理解这一点,我建议阅读 CompletionStage 的文档.

以下是您的代码按照我怀疑您想要的方式工作的示例:

public static void main(String[] args) {
CompletableFuture.runAsync(
() -> {
try {
read(data);
} catch (IOException ex) {
throw new UncheckedIOException(ex);
}
})
.orTimeout(1L, TimeUnit.SECONDS)
.join();
}

一些注意事项:

  • 二手CompletableFuture#runAsync(Runnable)创建一个“原始”阶段。当Runnable完成并且公共(public)ForkJoinPool用于执行Runnable时,此阶段将完成。

  • 如果抛出异常,runAsync 阶段中的 UncheckedIOException 将导致该阶段异常完成。

  • orTimeout(1L, TimeUnit.SECONDS) 调用返回的实例上调用 #join() 方法。现在,如果超时,对 join() 的调用将抛出一个包含 TimeoutExceptionCompletionException

警告:超时后,对 read 的调用不会中断1,这意味着它将继续在后台执行。这是因为 CompletableFuture 没有引用正在执行的线程,因此无法中断它们。

<小时/>

1。假设中断会 even have an effect .

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

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com