SpringBoot實(shí)現(xiàn)異步任務(wù)的項(xiàng)目實(shí)踐
一、使用背景
在多數(shù)的Java項(xiàng)目中,在很多的場(chǎng)景都是用同步的方式去實(shí)現(xiàn)模塊間的相互調(diào)用,在模塊調(diào)用間可能會(huì)造成一些延遲,本篇文章將使用SpringBoot 去實(shí)現(xiàn)異步之間的調(diào)用,提高系統(tǒng)的并發(fā)性能、用戶體驗(yàn)。
二、同步任務(wù)的優(yōu)缺點(diǎn)
2.1 優(yōu)點(diǎn)
簡(jiǎn)單直觀:同步任務(wù)的執(zhí)行是順序的,代碼執(zhí)行的流程清晰明了,易于理解和調(diào)試。
避免并發(fā)問題:同步任務(wù)在單線程中執(zhí)行,不會(huì)引發(fā)線程安全和數(shù)據(jù)一致性等并發(fā)問題。每次只有一個(gè)任務(wù)在執(zhí)行,避免了競(jìng)態(tài)條件和資源競(jìng)爭(zhēng)。
較少的資源消耗:同步任務(wù)不需要額外的線程資源來(lái)執(zhí)行,只使用主線程。這樣可以減少線程上下文切換的開銷,降低系統(tǒng)的資源消耗。
異常處理簡(jiǎn)單:同步任務(wù)中的異??梢灾苯訏伋?,易于捕獲和處理??梢栽诖a中使用try-catch語(yǔ)句來(lái)捕獲異常,進(jìn)行相應(yīng)的異常處理邏輯
2.2 缺點(diǎn)
阻塞主線程:同步任務(wù)需要等待任務(wù)執(zhí)行完成后才能繼續(xù)執(zhí)行下一個(gè)任務(wù),阻塞主線程。如果一個(gè)任務(wù)執(zhí)行時(shí)間過長(zhǎng),會(huì)導(dǎo)致整個(gè)系統(tǒng)的響應(yīng)變慢,影響用戶體驗(yàn)。
降低并發(fā)性能:由于同步任務(wù)需要按順序執(zhí)行,無(wú)法同時(shí)處理多個(gè)請(qǐng)求,降低了系統(tǒng)的并發(fā)性能和吞吐量。在高并發(fā)場(chǎng)景下,可能會(huì)導(dǎo)致系統(tǒng)處理能力不足。
響應(yīng)時(shí)間不穩(wěn)定:同步任務(wù)需要等待任務(wù)完成才返回結(jié)果,如果任務(wù)執(zhí)行時(shí)間不可預(yù)知或變化較大,會(huì)導(dǎo)致響應(yīng)時(shí)間不穩(wěn)定,難以控制和優(yōu)化。
潛在的死鎖風(fēng)險(xiǎn):當(dāng)同步任務(wù)中存在資源競(jìng)爭(zhēng)或循環(huán)依賴時(shí),可能會(huì)導(dǎo)致死鎖的產(chǎn)生。一旦發(fā)生死鎖,程序無(wú)法進(jìn)行進(jìn)一步的執(zhí)行,造成系統(tǒng)無(wú)法正常工作
2.3 總結(jié)
綜上所述,同步任務(wù)簡(jiǎn)單直觀,避免了并發(fā)問題和資源浪費(fèi),異常處理方便。但同時(shí)會(huì)阻塞主線程,降低并發(fā)性能,響應(yīng)時(shí)間不穩(wěn)定,并且潛在的死鎖風(fēng)險(xiǎn)
三、異步任務(wù)的優(yōu)缺點(diǎn)
3.1 優(yōu)點(diǎn)
提高系統(tǒng)的并發(fā)能力:異步方式將耗時(shí)操作從主線程中分離出來(lái),在后臺(tái)線程中執(zhí)行,不會(huì)阻塞主線程。這樣可以同時(shí)處理多個(gè)請(qǐng)求,提高系統(tǒng)的并發(fā)能力和吞吐量。
提升系統(tǒng)的響應(yīng)速度:由于異步方式不需要等待耗時(shí)操作的完成,主線程可以立即響應(yīng)其他請(qǐng)求。這樣可以減少用戶等待時(shí)間,提升系統(tǒng)的響應(yīng)速度,改善用戶體驗(yàn)。
優(yōu)化資源利用:異步方式可以在后臺(tái)線程中執(zhí)行耗時(shí)操作,釋放主線程的資源,減少資源浪費(fèi)。同時(shí),可以根據(jù)需求合理調(diào)整線程池的大小,靈活配置線程資源,以提高系統(tǒng)的資源利用效率。
簡(jiǎn)化編程模型:異步方式可以使用簡(jiǎn)單的注解(如@Async)或異步框架,簡(jiǎn)化編程模型。開發(fā)者不需要手動(dòng)處理線程的創(chuàng)建、管理和同步等細(xì)節(jié),減少開發(fā)復(fù)雜性
3.2 缺點(diǎn)
需要額外的線程資源:異步方式需要?jiǎng)?chuàng)建額外的線程來(lái)執(zhí)行耗時(shí)操作,增加了系統(tǒng)對(duì)線程資源的需求。如果線程資源不合理配置或管理不當(dāng),可能會(huì)導(dǎo)致性能下降、內(nèi)存溢出等問題。
可能引入復(fù)雜性:異步方式可能引入了代碼的復(fù)雜性。當(dāng)異步操作涉及到多個(gè)線程之間的協(xié)調(diào)和通信時(shí),可能需要更復(fù)雜的代碼邏輯和同步機(jī)制,增加了代碼維護(hù)的難度。
難以處理異常:異步操作的異常處理相對(duì)復(fù)雜,需要額外的關(guān)注和處理。異步方法的異常無(wú)法直接拋出到調(diào)用方,需要通過回調(diào)、Future對(duì)象或異步異常處理機(jī)制來(lái)進(jìn)行處理。
可能的競(jìng)態(tài)條件和并發(fā)問題:在多線程環(huán)境下,異步方式可能出現(xiàn)競(jìng)態(tài)條件、資源競(jìng)爭(zhēng)等并發(fā)問題,如線程安全性、數(shù)據(jù)一致性等。開發(fā)者需要進(jìn)行合理的線程同步和數(shù)據(jù)保護(hù),以避免潛在的問題
3.3 總結(jié)
異步方式可以提高系統(tǒng)的并發(fā)性能、響應(yīng)速度和資源利用效率,簡(jiǎn)化編程模型。然而,需要注意線程資源的合理配置和管理,處理異常和并發(fā)問題,以保證異步方式的穩(wěn)定和可靠性
四、Spring Boot 實(shí)現(xiàn)異步任務(wù)
4.0 項(xiàng)目結(jié)構(gòu)
4.1 pom.xml
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency>
4.2 編寫service類
import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; /** * 提供異步任務(wù)的服務(wù)類 */ @Service @Slf4j public class executeService { /** * 異步任務(wù):休眠10秒后,輸出"已執(zhí)行" */ @Async // 使用異步任務(wù) public void execute() { try { /* 假定有一個(gè)任務(wù)需要執(zhí)行10秒 */ Thread.sleep(10000); } catch (InterruptedException e) { throw new RuntimeException(e); } // 打印日志信息 log.info("任務(wù)已執(zhí)行完成"); } }
4.3 controller類
import com.hui.service.executeService; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; @RestController public class UserController { @Resource private executeService wakeService; @GetMapping("/execute") public String isWakeUp() { // 執(zhí)行任務(wù) wakeService.execute(); return "ok"; } }
4.4 SpringBoot 啟動(dòng)類
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableAsync; @EnableAsync // 啟動(dòng)異步任務(wù)注解 @SpringBootApplication public class AsyncApplication { public static void main(String[] args) { SpringApplication.run(AsyncApplication.class, args); } }
4.5 測(cè)試
訪問:http://localhost:8080/execute,當(dāng)帶上@Async 注解后,controller類會(huì)直接響應(yīng)"ok",而不用去等待10秒,再去響應(yīng)
10秒過后控制臺(tái)會(huì)輸出:“任務(wù)已執(zhí)行完成”
五、使用異步任務(wù)注意點(diǎn)
5.1 啟用異步支持
啟用異步支持:確保在配置類或主啟動(dòng)類上添加 @EnableAsync 注解,以激活 Spring 的異步處理功能
5.2 異步方法邊界
異步方法邊界:@Async 注解只能應(yīng)用在 public 方法上,因?yàn)?Spring 使用基于代理的機(jī)制,無(wú)法攔截非 public 方法的調(diào)用。
同時(shí),異步方法不能在同一個(gè)類中被調(diào)用,否則注解會(huì)失效,并報(bào)錯(cuò)。
到此這篇關(guān)于SpringBoot實(shí)現(xiàn)異步任務(wù)的項(xiàng)目實(shí)踐的文章就介紹到這了,更多相關(guān)SpringBoot 異步任務(wù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java靜態(tài)方法和實(shí)例方法區(qū)別詳解
這篇文章主要為大家詳細(xì)介紹了Java靜態(tài)方法和實(shí)例方法的區(qū)別,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-12-12java中快速創(chuàng)建帶初始值的List和Map實(shí)例
下面小編就為大家?guī)?lái)一篇java中快速創(chuàng)建帶初始值的List和Map實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來(lái)看看吧2017-10-10Java8流式API將實(shí)體類列表轉(zhuǎn)換為視圖對(duì)象列表的示例
這篇文章主要介紹了Java8流式API將實(shí)體類列表轉(zhuǎn)換為視圖對(duì)象列表的示例,文中有相關(guān)的代碼示例供大家參考,對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-11-11java通過HTTP接收json詳細(xì)實(shí)例代碼
Java作為一門廣泛使用的編程語(yǔ)言,很多開發(fā)人員會(huì)用它來(lái)進(jìn)行http請(qǐng)求,獲取json數(shù)據(jù),這篇文章主要給大家介紹了關(guān)于java通過HTTP接收json的相關(guān)資料,需要的朋友可以參考下2023-11-11Java面試常考之ConcurrentHashMap多線程擴(kuò)容機(jī)制詳解
幾乎所有的后端技術(shù)面試官都要在?ConcurrentHashMap?技術(shù)的使用和原理方面對(duì)小伙伴們進(jìn)行刁難,本文主要來(lái)和大家聊聊ConcurrentHashMap多線程的擴(kuò)容機(jī)制,希望對(duì)大家有所幫助2023-05-05Java數(shù)據(jù)結(jié)構(gòu)之KMP算法的實(shí)現(xiàn)
這篇文章主要為大家詳細(xì)介紹了Java數(shù)據(jù)結(jié)構(gòu)中KMP算法的原理與實(shí)現(xiàn),文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Java有一定的幫助,需要的可以參考一下2022-11-11MyBatis中獲取Mysql數(shù)據(jù)庫(kù)插入記錄的主鍵值的實(shí)現(xiàn)
本文主要介紹了MyBatis中獲取Mysql數(shù)據(jù)庫(kù)插入記錄的主鍵值的實(shí)現(xiàn),包含了三種實(shí)現(xiàn)方式,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-06-06