同步調用
,即:程序按定義的順序依次執行的過程,每一行代碼執行過程必須等待上一行代碼執行完畢后才執行。而異步調用
指:程序在執行時,無需等待執行的返回值可繼續執行后面的代碼。回調
。其主要是解決異步方法執行結果的處理方法,比如在希望異步調用結束時返回執行結果,這個時候就可以考慮使用回調機制。
需要在啟動類加入@EnableAsync
使異步調用@Async
注解生效
@Componentpublic class SyncService { @Async public void asyncEvent() throws InterruptedException { //休眠1s Thread.sleep(1000); //log.info("異步方法輸出:{}!", System.currentTimeMillis()); }}
在默認情況下,未設置TaskExecutor
時,默認是使用SimpleAsyncTaskExecutor
這個線程池,但此線程不是真正意義上的線程池,因為線程不重用,每次調用都會創建一個新的線程??赏ㄟ^控制臺日志輸出可以看出,每次輸出線程名都是遞增的。
調用的異步方法,不能為同一個類
的方法,因為Spring
在啟動掃描時會為其創建一個代理類,而同類調用時,還是調用本身的代理類的,所以和平常調用是一樣的。其他的注解如@Cache
等也是一樣的道理,就是Spring
的代理機制造成的。
創建一個自定義的ThreadPoolTaskExecutor
線程池:
@Configurationpublic class Config { /** * 配置線程池 * @return */ @Bean(name = "asyncPoolTaskExecutor") public ThreadPoolTaskExecutor getAsyncThreadPoolTaskExecutor() { ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor(); taskExecutor.setCorePoolSize(20); taskExecutor.setMaxPoolSize(200); taskExecutor.setQueueCapacity(25); taskExecutor.setKeepAliveSeconds(200); taskExecutor.setThreadNamePrefix("King-"); // 線程池對拒絕任務(無線程可用)的處理策略,目前只支持AbortPolicy、CallerRunsPolicy;默認為后者 taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); //調度器shutdown被調用時等待當前被調度的任務完成 taskExecutor.setWaitForTasksToCompleteOnShutdown(true); //等待時長 taskExecutor.setAwaitTerminationSeconds(60); taskExecutor.initialize(); return taskExecutor; } }
若需要在關閉線程池時等待當前調度任務完成后才開始關閉,可以通過簡單的配置,進行優雅的停機
策略配置。關鍵就是通過setWaitForTasksToCompleteOnShutdown(true)
和setAwaitTerminationSeconds
方法。
false
。 使用的是就只需要在@Async
加入線程池名稱即可:
@Async("asyncPoolTaskExecutor") public void asyncEvent() throws InterruptedException { //休眠1s Thread.sleep(1000); log.info("異步方法內部線程名稱:{}!", Thread.currentThread().getName()); }
異步回調及超時處理
需要異步回調的返回值時,就需要使用異步回調來完成了。主要就是通過Future
進行異步回調。
@Async("asyncPoolTaskExecutor")public Future<String> asyncEvent() throws InterruptedException { //休眠1s Thread.sleep(1000); log.info("異步方法內部線程名稱:{}!", Thread.currentThread().getName()); return new AsyncResult<>("異步方法返回值");}
AsyncResult
是Spring
提供的一個Future
接口的子類。然后通過isDone
方法,判斷是否已經執行完畢。
超時處理
對于Future
配置超時,很簡單,通過get
方法即可,具體如下:
//get方法會一直堵塞,直到等待執行完成才返回//get(long timeout, TimeUnit unit) 在設置時間類未返回結果,會直接排除異常TimeoutException,messages為nullString result = doFutrue.get(60, TimeUnit.SECONDS);//60s
超時后,會拋出異常TimeoutException
類,此時可進行統一異常捕獲即可
注意:
@Async所修飾的函數不要定義為static類型,這樣異步調用不會生效,
@Async調用中的事務處理機制
在@Async標注的方法,同時也適用了@Transactional進行了標注;在其調用數據庫操作之時,將無法產生事務管理的控制,原因就在于其是基于異步處理的操作。那該如何給這些操作添加事務管理呢?可以將需要事務管理操作的方法放置到異步方法內部,在內部被調用的方法上添加@Transactional. 例如: 方法A,使用了@Async/@Transactional來標注,但是無法產生事務控制的目的。方法B,使用了@Async來標注, B中調用了C、D,C/D分別使用@Transactional做了標注,則可實現事務控制的目的。 基于@Async調用中的異常處理機制 在異步方法中,如果出現異常,對于調用者caller而言,是無法感知的。
154204.html
本文由 貴州做網站公司 整理發布,部分圖文來源于互聯網,如有侵權,請聯系我們刪除,謝謝!
網絡推廣與網站優化公司(網絡優化與推廣專家)作為數字營銷領域的核心服務提供方,其價值在于通過技術手段與策略規劃幫助企業提升線上曝光度、用戶轉化率及品牌影響力。這...
在當今數字化時代,公司網站已成為企業展示形象、傳遞信息和開展業務的重要平臺。然而,對于許多公司來說,網站建設的價格是一個關鍵考量因素。本文將圍繞“公司網站建設價...
在當今的數字化時代,企業網站已成為企業展示形象、吸引客戶和開展業務的重要平臺。然而,對于許多中小企業來說,高昂的網站建設費用可能會成為其發展的瓶頸。幸運的是,隨...
英雄聯盟國慶出什么模式?目前英雄聯盟國慶是終極魔碼模式。在這種模式下,玩家只能攜帶一個召喚師技能,另一個召喚師技能會被其他英雄的終極技能隨機替換。進入游戲后,玩家可以選擇三個隨機英雄終極技能中的一個作為自己的召喚師技能。所選技能同時享受攻擊力和法術力加成,享受技能快速性??梢杂糜⑿鄣脑寄苓B續出招。2022年lol國慶開放什么模式?國慶沒有無限火力。無限火力2022年10月8日開始。超快速射擊,游...
手機里的文件夾可以刪除嗎? ;的手機文件夾可以刪除:1.緩存文件。在聽音樂、看視頻時,可以刪除系統上緩存的文件。2.軟件安裝包。我們下載軟件的時候,會有一個后綴為apk的軟件安裝包,也是沒用的,只能占用內存,可以刪除。3.在騰訊下載文件。對于自己下載的軟件,我們會放在下載里,可以刪除。此外,我們還可以在騰訊刪除聊天內容、圖片等內容。刪除手機應該注意的問題:1.不能刪除系統軟件。Android文件...
支付寶紅包的活動還有很多,只要你愿意找,就可以省下一筆零花錢。而這些紅包都是由支付寶出資,其目的是為了增加支付寶用戶的黏著度和使用率。支付寶是很多人經常使用的支付軟件。有時,使用支付寶轉賬時,會有轉賬獎金,僅限于轉賬賬戶。接下來,讓我們來談談如何使用支付寶的轉帳方式作為參考:]一步一步讀1。步驟。首先,打開支付寶。在手機首頁功能區,找到并點擊“卡套餐”模塊3。找到并選擇轉移獎金4。點擊轉賬紅包,進...