這篇文章主要介紹了Spring boot注解@Async線程池實(shí)例詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
從Spring3開始提供了@Async注解,該注解可以被標(biāo)注在方法上,以便異步地調(diào)用該方法。調(diào)用者將在調(diào)用時(shí)立即返回,方法的實(shí)際執(zhí)行將提交給Spring TaskExecutor的任務(wù)中,由指定的線程池中的線程執(zhí)行。
1. TaskExecutor
Spring異步線程池的接口類,其實(shí)質(zhì)是java.util.concurrent.Executor
Spring 已經(jīng)實(shí)現(xiàn)的異常線程池:
1. SimpleAsyncTaskExecutor:不是真的線程池,這個(gè)類不重用線程,每次調(diào)用都會(huì)創(chuàng)建一個(gè)新的線程。
2. SyncTaskExecutor:這個(gè)類沒有實(shí)現(xiàn)異步調(diào)用,只是一個(gè)同步操作。只適用于不需要多線程的地方
3. ConcurrentTaskExecutor:Executor的適配類,不推薦使用。如果ThreadPoolTaskExecutor不滿足要求時(shí),才用考慮使用這
個(gè)類
4. SimpleThreadPoolTaskExecutor:是Quartz的SimpleThreadPool的類。線程池同時(shí)被quartz和非quartz使用,才需要使用此類
5. ThreadPoolTaskExecutor :最常使用,推薦。 其實(shí)質(zhì)是對(duì)java.util.concurrent.ThreadPoolExecutor的包裝
2. @EnableAsync @Async
(1) springboot的啟動(dòng)類,@EnableAsync注解開啟異步調(diào)用
(2) spring對(duì)@Async定義異步任務(wù)
異步的方法有3種
1. 最簡(jiǎn)單的異步調(diào)用,返回值為void, 基于@Async無返回值調(diào)用,直接在使用類,使用方法(建議在使用方法)上,加上注解。若需要拋出異常,需手動(dòng)new一個(gè)異常拋出。
2. 帶參數(shù)的異步調(diào)用 異步方法可以傳入?yún)?shù)
3. 異常調(diào)用返回Future,不會(huì)被AsyncUncaughtExceptionHandler處理,需要我們?cè)诜椒ㄖ胁东@異常并處理或者在調(diào)用方在調(diào)用Futrue.get時(shí)捕獲異常進(jìn)行處理
3. @Async應(yīng)用默認(rèn)線程池
spring應(yīng)用默認(rèn)的線程池,指在@Async注解在使用時(shí),不指定線程池的名稱。查看源碼,@Async的默認(rèn)線程池為SimpleAsyncTaskExecutor。
默認(rèn)線程池的弊端
在線程池應(yīng)用中,參考阿里巴巴java開發(fā)規(guī)范:線程池不允許使用Executors去創(chuàng)建,不允許使用系統(tǒng)默認(rèn)的線程池,推薦通過ThreadPoolExecutor的方式,這樣的處理方式讓開發(fā)的工程師更加明確線程池的運(yùn)行規(guī)則,規(guī)避資源耗盡的風(fēng)險(xiǎn)。Executors各個(gè)方法的弊端:
newFixedThreadPool和newSingleThreadExecutor:主要問題是堆積的請(qǐng)求處理隊(duì)列可能會(huì)耗費(fèi)非常大的內(nèi)存,甚至OOM。
newCachedThreadPool和newScheduledThreadPool:要問題是線程數(shù)最大數(shù)是Integer.MAX_VALUE,可能會(huì)創(chuàng)建數(shù)量非常多的線程,甚至OOM。
@Async默認(rèn)異步配置使用的是SimpleAsyncTaskExecutor,該線程池默認(rèn)來一個(gè)任務(wù)創(chuàng)建一個(gè)線程,若系統(tǒng)中不斷的創(chuàng)建線程,最終會(huì)導(dǎo)致系統(tǒng)占用內(nèi)存過高,引發(fā)OutOfMemoryError錯(cuò)誤。針對(duì)線程創(chuàng)建問題,SimpleAsyncTaskExecutor提供了限流機(jī)制,通過concurrencyLimit屬性來控制開關(guān),當(dāng)concurrencyLimit>=0時(shí)開啟限流機(jī)制,默認(rèn)關(guān)閉限流機(jī)制即concurrencyLimit=-1,當(dāng)關(guān)閉情況下,會(huì)不斷創(chuàng)建新的線程來處理任務(wù)。基于默認(rèn)配置,SimpleAsyncTaskExecutor并不是嚴(yán)格意義的線程池,達(dá)不到線程復(fù)用的功能。
4. @Async應(yīng)用自定義線程池
自定義線程池,可對(duì)系統(tǒng)中線程池更加細(xì)粒度的控制,方便調(diào)整線程池大小配置,線程執(zhí)行異常控制和處理。在設(shè)置系統(tǒng)自定義線程池代替默認(rèn)線程池時(shí),雖可通過多種模式設(shè)置,但替換默認(rèn)線程池最終產(chǎn)生的線程池有且只能設(shè)置一個(gè)(不能設(shè)置多個(gè)類繼承AsyncConfigurer)。自定義線程池有如下模式:
新聞熱點(diǎn)
疑難解答
圖片精選