java - 在 Spring Boot 的 @Async 注解中使用 CompletableFuture.supplyAsync 和 CompletableFuture.completedFuture
问题描述
我有以下方法:
@EnableAsync
@Service
Class MyService{
private String processRequest() {
log.info("Start processing request");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
log.info("Completed processing request");
return RESULT;
}
@Async
public CompletableFuture<String> getSupplyAsyncResult(){
CompletableFuture<String> future
= CompletableFuture.supplyAsync(this::processRequest);
return future;
}
@Async
public CompletableFuture<String> getCompletedFutureResult(){
CompletableFuture<String> future
= CompletableFuture.supplyAsync(this::processRequest);
return future;
}
以及控制器中的以下端点:
@RequestMapping(path = "/asyncSupplyAsync", method = RequestMethod.GET)
public CompletableFuture<String> getValueAsyncUsingCompletableFuture() {
log.info("Request received");
CompletableFuture<String> completableFuture
= myService.getSupplyAsyncResult();
log.info("Servlet thread released");
return completableFuture;
}
和
@RequestMapping(path = "/asyncCompletable", method = RequestMethod.GET)
public CompletableFuture<String> getValueAsyncUsingCompletableFuture() {
log.info("Request received");
CompletableFuture<String> completableFuture
= myService.getCompletedFutureResult();
log.info("Servlet thread released");
return completableFuture;
}
为什么有人会在 Spring 端点的 @Async 方法中使用completableFuture.supplyAsync ?我认为使用completableFuture.completedFuture 更合适,请分享您的观点。
解决方案
它们一开始就服务于完全不同的目的。在考虑处理一个或另一个需要多少之前,您可能首先想了解它们是如何工作的(所以很少的调用并不表示慢/快;这些数字在这种情况下毫无意义)。
这是您的相同示例:
public class SO64718973 {
public static void main(String[] args) {
System.out.println("dispatching to CF...");
//CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> processRequest());
CompletableFuture<String> future = CompletableFuture.completedFuture(processRequest());
System.out.println("done dispatching to CF...");
future.join();
}
private static String processRequest() {
System.out.println("Start processing request");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("Completed processing request");
return "RESULT";
}
}
您可以运行它,然后更改实现(通过取消注释CompletableFuture.supplyAsync
)并查看它们System.out.println
发生的位置。您会注意到,completedFuture
它将阻塞main
线程,直到它被执行,而supplyAsync
将在不同的线程中运行。所以这不是一个是错的,一个是错的,这取决于你的用例。
一般来说,不CompletableFuture.supplyAsync
为它配置一个池就使用它不是一个好主意;否则它将消耗来自ForkJoinPool
.
推荐阅读
- javascript - 上下文不更新异步函数中的 React
- javascript - 如何对数组中的对象进行分组并根据对象属性对其进行排序
- javascript - Vue.js - Div - 使用计算的字符串结果作为类名
- r - R数组的“跨度”
- java - Locale.getISOCountries() 在 android 设备中返回不同的列表(在三星 Galaxy S10 上测试)JAVA
- python - ZeroMQ 在 Unity 中不起作用,但可以作为控制台应用程序使用
- ruby-on-rails - 无法在非对象上调用 jsonb_each - rails 更新后查询中断
- javascript - 如何在 Vue 3 中使用 Vue.prototype 或全局变量?
- selenium - 如何在没有任何其他属性的 selenium webdriver 中找到 span 元素?
- angular - 错误:未捕获(承诺):错误:无法匹配任何路由。URL 段:'en'