SpringBoot異步及線程池配置


異步方法注解@Async

在SpringBoot中進行異步處理,可以使用異步注解@Async和@EnableAsync。
@Async注解表示異步,如:@Async("asyncServiceExecutor"),
后面的參數asyncServiceExecutor對應於自定義的線程池配置類(在以下例子中為ExecutorConfig) 中的線程池方法名
如果不寫后面的參數,直接用@Async,則是使用默認的線程池。

Future實現類獲取異步處理結果

如果想要獲取異步處理的結果,可以通過Future接口的實現類調用get()方法獲得。
Future接口的常見實現類有FutureTask。
在SpringBoot中,一般用 AsyncResult作為異步結果。

示例

注意:以下示例中的@Slf4j注解是屬於lombok的注解,如果不想使用lombok,可以直接用常規的日志聲明變量代替。
1.AsyncService如下:

@Component
@Slf4j
public class AsyncService {
    /**
     * @Async注解表示異步,后面的參數對應於線程池配置類ExecutorConfig中的方法名asyncServiceExecutor(),
     * 如果不寫后面的參數,直接使用@Async注解,則是使用默認的線程池
     * Future<String>為異步返回的結果。可以通過get()方法獲取結果。
     *
     */
    @Async("asyncServiceExecutor")
    public Future<String> getDataResult( ){
        log.info("開始異步處理");
        String result="asyncResultTest";
        return new AsyncResult<String>(result);
    }
}

線程池ThreadPoolTaskExecutor

SpringBoot中的線程池一般用ThreadPoolTaskExecutor 類。
ThreadPoolTaskExecutor繼承關系如下:

ThreadPoolTaskExecutor extends ExecutorConfigurationSupport implements AsyncListenableTaskExecutor, SchedulingTaskExecutor

關系結構圖為:

2.自定義線程池配置如下:

@Slf4j
@Configuration
public class ExecutorConfig {
    @Bean
    public Executor asyncServiceExecutor() {
        log.info("start asyncServiceExecutor");
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        //配置核心線程數
        executor.setCorePoolSize(5);
        //配置最大線程數
        executor.setMaxPoolSize(5);
        //配置隊列大小
        executor.setQueueCapacity(99999);
        //配置線程池中的線程的名稱前綴
        executor.setThreadNamePrefix("async-service-");

        // 設置拒絕策略:當pool已經達到max size的時候,如何處理新任務
        // CALLER_RUNS:不在新線程中執行任務,而是有調用者所在的線程來執行
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        //執行初始化
        executor.initialize();
        return executor;
    }
}

3.UserService 如下:

@Service
@Slf4j
public class UserService {
    @Autowired
    private AsyncService asyncService;

    /**
     * 調用異步服務,獲取異步結果。
     * @return
     */
    public String getAsyncResult()  {
        Future<String>  future=asyncService.getDataResult();
        String result=null;
        try{
            result =future.get();
        }catch (InterruptedException | ExecutionException e) {
            log.error("error:{}",e.getMessage());
        }
        log.info("異步處理結果為:{}",result);
        return result;
    }

}

@EnableAsync開啟異步

@EnableAsync表示開啟異步,可以放在@Controller層上方,也可以放在Application類的上方。

@Controller
@EnableAsync
public class UserController {
    @Autowired
    private UserService userService;

    @GetMapping("/user/query")
    @ResponseBody
    public String getUserData(){
        return userService.getAsyncResult();
    }
}

參考資料:
https://blog.csdn.net/boling_cavalry/article/details/79120268


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM