【发布时间】:2020-05-06 05:53:22
【问题描述】:
我创建了一个实现异步重试模式的方法。实际上,我希望当我调用此方法时,请求应该在一个单独的线程中处理,并且应该延迟重试
private <R> CompletableFuture<R> withRetryRequest(Supplier<CompletableFuture<R>> supplier, int maxRetries) {
CompletableFuture<R> f = supplier.get();
for (int i = 0; i < maxRetries; i++) {
f = f.thenApply(CompletableFuture::completedFuture)
.exceptionally(t -> {
try {
Thread.sleep(10 * 1000);
} catch (Exception exp) {
log.log(Level.SEVERE, "Error while delay executing", exp);
}
return supplier.get();
})
.thenCompose(Function.identity());
}
return f;
}
这里是调用者部分:
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(PropUtil.getPropUtil().THREAD_POOL_SIZE);
CompletableFuture<Boolean> retry = this.withRetryRequest(() -> runDoorOpenProcedure(req), req.getRetryCount());
final CompletableFuture<Boolean> retryFinal = retry;
CompletableFuture<CompletableFuture<Boolean>> retryRes = CompletableFuture.supplyAsync(() -> retryFinal, executor);
Boolean success = retry.get().join();
但似乎调用根本不是异步的。我在这里做错了什么,有人可以看看这个吗?
【问题讨论】:
-
你怎么知道它不叫异步?你必须在
CompletableFuture.supplyAsync和retry.get().join()之间做点什么,目前,你的主线程正在等待。在supplyAsync之后打印一些东西 -
或者你可以打印
withRetryRequest里面的thread_id。Thread currentThread = Thread.currentThread(); System.out.println("thread id:" + currentThread.getId()); -
我已经在 withRetryRequest 中打印了 ThreadId,它似乎是所有请求的同一个线程。 “你怎么知道它不叫异步?”我从 https 请求中调用此代码,并且每次 HTTP 调用都等到重试完成,所以这总体上不是异步的。我没有在我做错的地方得到这个。
-
我明白你的意思。你的 HTTP 请求等待的原因是因为你
retry.get().join();。我觉得你需要另辟蹊径来写这个逻辑,CompletedFuture 不适合这种场景。 -
每个 HTTP 请求都是通过发送请求并等待结果来工作的。要使其异步,您需要对设置进行根本更改,例如在浏览器中运行脚本以处理异步结果。
标签: java java-8 completable-future threadpoolexecutor