Java中注解@Async實(shí)現(xiàn)異步及導(dǎo)致失效原因分析
前言
在 Java 中,@Async 注解用于表明一個(gè)方法是異步執(zhí)行的。這意味著方法會(huì)在調(diào)用時(shí)立即返回,而不會(huì)等待方法體內(nèi)的代碼執(zhí)行完畢。這對(duì)于需要異步執(zhí)行長時(shí)間操作的方法非常有用,比如發(fā)送郵件、處理大量數(shù)據(jù)等。
1.使用實(shí)例
假設(shè)有一個(gè) Spring Boot 項(xiàng)目,我們希望在某個(gè)方法中發(fā)送郵件但不影響主流程,可以這樣使用 @Async 注解:
1. 配置類添加@EnableAsync:
import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableAsync; @Configuration @EnableAsync public class AsyncConfig { // 異步方法的配置類,確保@EnableAsync開啟異步方法執(zhí)行的支持 }
2. Service 類中的異步方法:
import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; @Service public class EmailService { @Async public void sendEmail(String recipient, String message) { // 異步發(fā)送郵件的邏輯 System.out.println("Sending email to " + recipient); // 實(shí)際的郵件發(fā)送邏輯 } }
上述代碼中,sendEmail 方法被 @Async 注解修飾,表示這個(gè)方法是異步執(zhí)行的。
3. 調(diào)用異步方法:
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; @Controller public class MyController { @Autowired private EmailService emailService; @GetMapping("/sendEmail") @ResponseBody public String handleRequest(@RequestParam String recipient, @RequestParam String message) { emailService.sendEmail(recipient, message); return "Email sent asynchronously"; } }
在這個(gè)例子中,調(diào)用 /sendEmail 接口時(shí),sendEmail 方法被異步執(zhí)行,不會(huì)阻塞主線程的返回響應(yīng)。
2.失效情況
@Async 注解失效的一些常見情況和注意事項(xiàng):
1. 內(nèi)部調(diào)用問題:
- @Async 僅在外部調(diào)用時(shí)生效,即使在同一個(gè)類的內(nèi)部調(diào)用 @Async 方法,也不會(huì)異步執(zhí)行,因?yàn)?Spring 使用 AOP 實(shí)現(xiàn)異步方法,需要通過代理對(duì)象調(diào)用才能生效。
2. 未正確配置異步支持:
- 如果忘記在配置類上添加 @EnableAsync 注解,或者異步方法沒有被 Spring 容器管理(沒有被 @Component 或其衍生注解標(biāo)記),則 @Async 也會(huì)失效。
3. 返回值問題:
- 異步方法不能有返回值,如果有返回值 Spring 會(huì)拋出異常。因此異步方法通常被設(shè)計(jì)為 void 返回類型。
4. 線程池配置問題:
- 默認(rèn)情況下,Spring 使用一個(gè)默認(rèn)的線程池來處理異步方法。如果需要自定義線程池,可以在配置類中使用 @Bean 方法定義一個(gè) TaskExecutor Bean,并在 @Async 注解中指定使用的線程池名字(通過 executor 屬性)。
綜上所述,@Async 注解在合適的情況下可以有效地實(shí)現(xiàn)異步方法的執(zhí)行,但在使用時(shí)需要注意以上的失效情況,以確保其按預(yù)期工作。
總結(jié)
到此這篇關(guān)于Java中注解@Aysn實(shí)現(xiàn)異步及導(dǎo)致失效原因分析的文章就介紹到這了,更多相關(guān)Java @Aysn異步及失效原因內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
基于Spring Web Jackson對(duì)RequestBody反序列化失敗的解決
這篇文章主要介紹了基于Spring Web Jackson對(duì)RequestBody反序列化失敗的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-09-09spring boot如何實(shí)現(xiàn)切割分片上傳
這篇文章主要介紹了spring boot如何實(shí)現(xiàn)切割分片上傳,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-12-12java Class.getSimpleName() 詳解及用法
這篇文章主要介紹了java Class.getSimpleName() 詳解及用法的相關(guān)資料,需要的朋友可以參考下2017-02-02解決Springboot集成Redis集群配置公網(wǎng)IP連接報(bào)私網(wǎng)IP連接失敗問題
在Springboot 集成 Redis集群配置公網(wǎng)IP連接報(bào)私網(wǎng)IP連接失敗,一直報(bào)私有IP連接失敗,所以本文小編給大家介紹了如何解決報(bào)錯(cuò)問題,如果有遇到相同問題的同學(xué),可以參考閱讀本文2023-10-10@PathVariable注解,讓spring支持參數(shù)帶值功能的案例
這篇文章主要介紹了@PathVariable注解,讓spring支持參數(shù)帶值功能的案例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-02-02SpringBoot利用自定義注解實(shí)現(xiàn)隱私數(shù)據(jù)脫敏(加密顯示)的解決方案
這兩天在整改等保測(cè)出的問題,里面有一個(gè)“用戶信息泄露”的風(fēng)險(xiǎn)項(xiàng)(就是后臺(tái)系統(tǒng)里用戶的一些隱私數(shù)據(jù)直接明文顯示了),其實(shí)指的就是要做數(shù)據(jù)脫敏,本文給大家介紹了SpringBoot利用自定義注解實(shí)現(xiàn)隱私數(shù)據(jù)脫敏(加密顯示)的解決方案,需要的朋友可以參考下2023-11-11如何更優(yōu)雅的關(guān)閉java文本、網(wǎng)絡(luò)等資源
這篇文章主要介紹了如何更優(yōu)雅的關(guān)閉java文本、網(wǎng)絡(luò)等資源,在 finally 的關(guān)閉代碼中,還要再來一個(gè) try/catch,看著是不是很難受,很不優(yōu)雅,很想干掉這個(gè) finally!,需要的朋友可以參考下2019-06-06ThreadPoolExecutor參數(shù)的用法及說明
這篇文章主要介紹了ThreadPoolExecutor參數(shù)的用法及說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03springboot-jta-atomikos多數(shù)據(jù)源事務(wù)管理實(shí)現(xiàn)
本文主要介紹了springboot-jta-atomikos多數(shù)據(jù)源事務(wù)管理實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03