CompletableFuture 在超时时未完成
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
return 一个 新实例 ,它创建了一种 "chain" 阶段。每个阶段都由其 "parent" 阶段的完成触发。为了完全理解这一点,我建议阅读 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)
创建了一个 "primordial" 舞台。当 Runnable
完成并且公共 ForkJoinPool
用于执行 Runnable
.
时,此阶段将完成
如果抛出 runAsync
阶段中的 UncheckedIOException
将导致该阶段异常完成。
#join()
方法在实例 return 上被 orTimeout(1L, TimeUnit.SECONDS)
调用调用。现在,如果超时结束,对 join()
的调用将抛出 CompletionException
包装 TimeoutException
.
警告:调用read
没有被打断1超时后会继续执行在后台。这是因为 CompletableFuture
没有引用正在执行的线程,因此无法中断它们。
1.假设中断会 .
我有一个从输入流读取的方法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
return 一个 新实例 ,它创建了一种 "chain" 阶段。每个阶段都由其 "parent" 阶段的完成触发。为了完全理解这一点,我建议阅读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)
创建了一个 "primordial" 舞台。当Runnable
完成并且公共ForkJoinPool
用于执行Runnable
. 时,此阶段将完成
如果抛出
runAsync
阶段中的UncheckedIOException
将导致该阶段异常完成。#join()
方法在实例 return 上被orTimeout(1L, TimeUnit.SECONDS)
调用调用。现在,如果超时结束,对join()
的调用将抛出CompletionException
包装TimeoutException
.
警告:调用read
没有被打断1超时后会继续执行在后台。这是因为 CompletableFuture
没有引用正在执行的线程,因此无法中断它们。
1.假设中断会