Java 不等待异步调用响应
Posted
技术标签:
【中文标题】Java 不等待异步调用响应【英文标题】:Java doesn't wait for asynchronous call response 【发布时间】:2021-11-24 14:54:45 【问题描述】:我在 Java 中使用ExecutorService
创建一个线程池,其中每个线程执行一些异步任务/调用另一个服务。我不想等待响应,而是在响应到达时返回。
ExecutorService executor = Executors.newFixedThreadPool(5); // Class var
// Method
Future<Object> future = executor.submit(new TransportService(requestVO));
Object response = future.get(5, TimeUnit.SECONDS); // blocking
这样做会等待第一个请求完成,然后返回结果。问题是第二个请求必须等待第一个请求的响应返回,并且仅在此之后处理。如果我使用 CompletableFuture 的 supplyAsync()
方法也会发生同样的事情,因为我还必须使用 join()
来获取响应。
我希望所有请求都通过并在响应到达时返回。这是可以实现的吗?流程仍然需要同步。
【问题讨论】:
第二个请求在哪里?您是否在循环中运行给定的代码? @StephanStahlmann 我正在循环调用该方法。 您的标题与您的问题相反。您希望 Java 不等待,但您(尚未)找到可以让您这样做的 API。 【参考方案1】:您或许可以使用CompletableFuture
将异步任务提供给ExecutorService
:
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "foo", Executors.newSingleThreadExecutor());
future.thenAccept(s -> System.out.println("done: " + s));
CompletableFuture
有多个 then...
方法用于在完成时链接后续操作。
【讨论】:
【参考方案2】:您需要在集合中添加期货,然后在最后调用 join/get。
Collection<Future<Object>> futures = new ArrayList<>();
// schedule calls independantly
for(Request vo: requests)
futures.add(executor.submit(new TransportService(requestVO)));
// actually handle result
for(Future<Object> future: futures)
Object response = future.get(5, TimeUnit.SECONDS);
在这种情况下,您最多可以安排五个作业。
【讨论】:
以上是关于Java 不等待异步调用响应的主要内容,如果未能解决你的问题,请参考以下文章