在 spring 引导中的 @Async 注释中使用 CompletableFuture.supplyAsync 和 CompletableFuture.completedFuture
use of CompletableFuture.supplyAsync and CompletableFuture.completedFuture within @Async annotation in spring boot
我有以下方法:
@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更合适,请分享您的意见。
它们最初的目的完全不同。在考虑一个或另一个处理需要多少时间之前,您可能想首先了解它们是如何工作的(所以很少的调用并不表示 slow/fast 无论如何;这些数字在这种情况下没有任何意义)。
这是与您相同的示例:
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
.
的线程
我有以下方法:
@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更合适,请分享您的意见。
它们最初的目的完全不同。在考虑一个或另一个处理需要多少时间之前,您可能想首先了解它们是如何工作的(所以很少的调用并不表示 slow/fast 无论如何;这些数字在这种情况下没有任何意义)。
这是与您相同的示例:
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
.