簡體   English   中英

在 Spring Boot 的 @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更合適,請分享您的意見。

它們一開始就服務於完全不同的目的。 在您考慮處理一個或另一個需要多少時間之前,您可能首先想了解它們是如何工作的(無論如何,調用很少並不表示慢/快;這些數字在這種情況下沒有任何意義)。

這是您擁有的相同示例:

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線程。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM