您好,登錄后才能下訂單哦!
這篇文章主要介紹Spring Boot集成中如何異步調用Async,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!
什么是異步調用?
異步調用是相對于同步調用而言的,同步調用是指程序按預定順序一步步執行,每一步必須等到上一步執行完后才能執行,異步調用則無需等待上一步程序執行完即可執行。
異步處理方式
調用之后,不返回任何數據。
調用之后,返回數據,通過Future來獲取返回數據
如何實現異步調用?
多線程,這是很多人第一眼想到的關鍵詞,沒錯,多線程就是一種實現異步調用的方式。
在非spring目項目中我們要實現異步調用的就是使用多線程方式,可以自己實現Runable接口或者集成Thread類,或者使用jdk1.5以上提供了的Executors線程池。
StrngBoot中則提供了很方便的方式執行異步調用。
按照官方示例開擼
代碼入下
maven依賴:
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.3.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies>
啟動類:添加@EnableAsync注解
@SpringBootApplication @EnableAsync public class Application{ public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
Controller
只需在需要異步執行方法上添加@Async注解
@RestController @RequestMapping("") public class AsyncTaskController { @RequestMapping("") public String doTask() throws InterruptedException{ long currentTimeMillis = System.currentTimeMillis(); this.task1(); this.task2(); this.task3(); long currentTimeMillis1 = System.currentTimeMillis(); return "task任務總耗時:"+(currentTimeMillis1-currentTimeMillis)+"ms"; } @Async public void task1() throws InterruptedException{ long currentTimeMillis = System.currentTimeMillis(); Thread.sleep(1000); long currentTimeMillis1 = System.currentTimeMillis(); System.out.println("task1任務耗時:"+(currentTimeMillis1-currentTimeMillis)+"ms"); } @Async public void task2() throws InterruptedException{ long currentTimeMillis = System.currentTimeMillis(); Thread.sleep(2000); long currentTimeMillis1 = System.currentTimeMillis(); System.out.println("task2任務耗時:"+(currentTimeMillis1-currentTimeMillis)+"ms"); } @Async public void task3() throws InterruptedException{ long currentTimeMillis = System.currentTimeMillis(); Thread.sleep(3000); long currentTimeMillis1 = System.currentTimeMillis(); System.out.println("task3任務耗時:"+(currentTimeMillis1-currentTimeMillis)+"ms"); } }
main函數運行spirngboot項目,啟動完成后瀏覽器訪問:http://localhost:8080/
控制臺:
task1任務耗時:1012ms task2任務耗時:2009ms task3任務耗時:3004ms
等了一段瀏覽器時候輸出入下:
task任務總耗時:6002ms
異步并沒有執行!
難道是代碼寫錯了?反復檢查了好幾遍,并沒有發現什么明顯錯誤,想起spring對@Transactional注解時也有類似問題,spring掃描時具有@Transactional注解方法的類時,是生成一個代理類,由代理類去開啟關閉事務,而在同一個類中,方法調用是在類體內執行的,spring無法截獲這個方法調用。
豁然開朗,將異步任務單獨放到一個類中,調整代碼入下:
Controller
@RequestMapping("") @RestController public class AsyncTaskController { @Autowired private AsyncTask asyncTask; @RequestMapping("") public String doTask() throws InterruptedException{ long currentTimeMillis = System.currentTimeMillis(); asyncTask.task1(); asyncTask.task2(); asyncTask.task3(); long currentTimeMillis1 = System.currentTimeMillis(); return "task任務總耗時:"+(currentTimeMillis1-currentTimeMillis)+"ms"; } }
異步任務類
@Component public class AsyncTask { @Async public void task1() throws InterruptedException{ long currentTimeMillis = System.currentTimeMillis(); Thread.sleep(1000); long currentTimeMillis1 = System.currentTimeMillis(); System.out.println("task1任務耗時:"+(currentTimeMillis1-currentTimeMillis)+"ms"); } @Async public void task2() throws InterruptedException{ long currentTimeMillis = System.currentTimeMillis(); Thread.sleep(2000); long currentTimeMillis1 = System.currentTimeMillis(); System.out.println("task2任務耗時:"+(currentTimeMillis1-currentTimeMillis)+"ms"); } @Async public void task3() throws InterruptedException{ long currentTimeMillis = System.currentTimeMillis(); Thread.sleep(3000); long currentTimeMillis1 = System.currentTimeMillis(); System.out.println("task3任務耗時:"+(currentTimeMillis1-currentTimeMillis)+"ms"); } }
控制臺:
task1任務耗時:1012ms task2任務耗時:2009ms task3任務耗時:3004ms
訪問瀏覽器結果入下:
task任務總耗時:19ms
異步調用成功!
如何知道三個異步任務什么時候執行完,執行的結果怎樣呢?可以采用添加Fature回調方式判斷
代碼入下:
異步任務類
@Component public class AsyncTask { @Async public Future<String> task1() throws InterruptedException{ long currentTimeMillis = System.currentTimeMillis(); Thread.sleep(1000); long currentTimeMillis1 = System.currentTimeMillis(); System.out.println("task1任務耗時:"+(currentTimeMillis1-currentTimeMillis)+"ms"); return new AsyncResult<String>("task1執行完畢"); } @Async public Future<String> task2() throws InterruptedException{ long currentTimeMillis = System.currentTimeMillis(); Thread.sleep(2000); long currentTimeMillis1 = System.currentTimeMillis(); System.out.println("task2任務耗時:"+(currentTimeMillis1-currentTimeMillis)+"ms"); return new AsyncResult<String>("task2執行完畢"); } @Async public Future<String> task3() throws InterruptedException{ long currentTimeMillis = System.currentTimeMillis(); Thread.sleep(3000); long currentTimeMillis1 = System.currentTimeMillis(); System.out.println("task3任務耗時:"+(currentTimeMillis1-currentTimeMillis)+"ms"); return new AsyncResult<String>("task3執行完畢"); } }
Controller
@RequestMapping("") @RestController public class AsyncTaskController { @Autowired private AsyncTask asyncTask; @RequestMapping("") public String doTask() throws InterruptedException{ long currentTimeMillis = System.currentTimeMillis(); Future<String> task1 = asyncTask.task1(); Future<String> task2 = asyncTask.task2(); Future<String> task3 = asyncTask.task3(); String result = null; for (;;) { if(task1.isDone() && task2.isDone() && task3.isDone()) { // 三個任務都調用完成,退出循環等待 break; } Thread.sleep(1000); } long currentTimeMillis1 = System.currentTimeMillis(); result = "task任務總耗時:"+(currentTimeMillis1-currentTimeMillis)+"ms"; return result; } }
控制臺輸出:
task1任務耗時:1000ms task2任務耗時:2001ms task3任務耗時:3001ms
瀏覽器輸出:
task任務總耗時:4015ms
異步調用成功,并且在所有任務都完成時程序才返回了結果!
以上是“Spring Boot集成中如何異步調用Async”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。