[英]CompletableFuture does not complete on timeout
我有一个方法read
从输入流中读取。 如果超时后read
尚未完成,我想完成未来。
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();
}
但是,当我运行此代码时,它不会在超时前完成并等待输入流。
您的代码至少有两个问题:
什么都没有被执行。 您创建一个CompletableFuture
,然后在其上调用thenRunAsync
。 thenRunAsync
创建的阶段只会在前一阶段完成后触发。 由于您从未完成原始CompletableFuture
因此这永远不会发生。 你也最终加入了一个永远不会完成的未来。
你加入了错误的CompletableFuture
。 thenRunAsync
和orTimeout
等方法返回一个新实例,该实例创建了一种“阶段链”。 每个阶段都由其“父”阶段的完成触发。 为了完全理解这一点,我建议阅读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
完成并且公共ForkJoinPool
用于执行Runnable
时,此阶段将完成。
如果,扔的时候,在UncheckedIOException
在runAsync
阶段将导致阶段格外完成。
#join()
方法在orTimeout(1L, TimeUnit.SECONDS)
调用返回的实例上调用。 现在,如果超时过去,则调用join()
将抛出一个CompletionException
包装TimeoutException
。
警告:当超时过去时, read
调用不会被中断1 ,这意味着它将继续在后台执行。 这是因为CompletableFuture
没有对正在执行的线程的引用,因此不能中断它们。
1. 假设中断甚至会产生影响。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.