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