欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring Boot集成教程之異步調用Async

 更新時間:2018年03月22日 11:12:09   作者:再見尼羅河  
在項目中,當訪問其他人的接口較慢或者做耗時任務時,不想程序一直卡在耗時任務上,想程序能夠并行執(zhí)行,我們可以使用多線程來并行的處理任務,也可以使用spring提供的異步處理方式@Async。需要的朋友們下面來一起看看吧。

前言

本文主要給大家介紹了關于Spring Boot集成之異步調用Async的相關內容,分享出來供大家參考學習,下面話不多說了,來一起看看詳細的介紹吧。

什么是異步調用?

異步調用是相對于同步調用而言的,同步調用是指程序按預定順序一步步執(zhí)行,每一步必須等到上一步執(zhí)行完后才能執(zhí)行,異步調用則無需等待上一步程序執(zhí)行完即可執(zhí)行。

異步處理方式

  • 調用之后,不返回任何數(shù)據(jù)。
  • 調用之后,返回數(shù)據(jù),通過Future來獲取返回數(shù)據(jù)

如何實現(xiàn)異步調用?

多線程,這是很多人第一眼想到的關鍵詞,沒錯,多線程就是一種實現(xiàn)異步調用的方式。

在非spring目項目中我們要實現(xiàn)異步調用的就是使用多線程方式,可以自己實現(xiàn)Runable接口或者集成Thread類,或者使用jdk1.5以上提供了的Executors線程池。

StrngBoot中則提供了很方便的方式執(zhí)行異步調用。

按照官方示例開擼

代碼入下

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

只需在需要異步執(zhí)行方法上添加@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函數(shù)運行spirngboot項目,啟動完成后瀏覽器訪問:http://localhost:8080/

控制臺:

task1任務耗時:1012ms 
task2任務耗時:2009ms 
task3任務耗時:3004ms 

等了一段瀏覽器時候輸出入下:

task任務總耗時:6002ms 

異步并沒有執(zhí)行!

難道是代碼寫錯了?反復檢查了好幾遍,并沒有發(fā)現(xiàn)什么明顯錯誤,想起spring對@Transactional注解時也有類似問題,spring掃描時具有@Transactional注解方法的類時,是生成一個代理類,由代理類去開啟關閉事務,而在同一個類中,方法調用是在類體內執(zhí)行的,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 

異步調用成功!

如何知道三個異步任務什么時候執(zhí)行完,執(zhí)行的結果怎樣呢?可以采用添加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執(zhí)行完畢"); 
 } 
  
 @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執(zhí)行完畢"); 
 } 
 @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執(zhí)行完畢"); 
 } 
} 

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()) { 
    // 三個任務都調用完成,退出循環(huán)等待 
    break; 
   } 
   Thread.sleep(1000); 
  } 
  long currentTimeMillis1 = System.currentTimeMillis(); 
  result = "task任務總耗時:"+(currentTimeMillis1-currentTimeMillis)+"ms"; 
  return result; 
 } 
} 

控制臺輸出:

task1任務耗時:1000ms 
task2任務耗時:2001ms 
task3任務耗時:3001ms 

瀏覽器輸出:

task任務總耗時:4015ms

異步調用成功,并且在所有任務都完成時程序才返回了結果!

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。

相關文章

  • Java設計者模式簡單工廠模式解析

    Java設計者模式簡單工廠模式解析

    這篇文章主要介紹了Java設計者模式簡單工廠模式解析,介紹了其簡介,實例以及優(yōu)缺點分析,具有一定參考價值,需要的朋友可以了解下。
    2017-11-11
  • Java編程實現(xiàn)調用com操作Word方法實例代碼

    Java編程實現(xiàn)調用com操作Word方法實例代碼

    這篇文章主要介紹了Java編程實現(xiàn)調用com操作Word方法實例代碼,代碼注釋很詳細,在這里分給大家,需要的朋友可以參考下。
    2017-09-09
  • Spring中@RestControllerAdvice注解的使用詳解

    Spring中@RestControllerAdvice注解的使用詳解

    這篇文章主要介紹了Spring中@RestControllerAdvice注解的使用詳解,@RestControllerAdvice是一個組合注解,由@ControllerAdvice、@ResponseBody組成,而@ControllerAdvice繼承了@Component,需要的朋友可以參考下
    2024-01-01
  • 詳解Java中方法重寫與重載的區(qū)別(面試高頻問點)

    詳解Java中方法重寫與重載的區(qū)別(面試高頻問點)

    這篇文章主要介紹了Java中方法重寫與重載的區(qū)別(面試高頻問點),本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-03-03
  • Java中空指針異常該如何避免詳解

    Java中空指針異常該如何避免詳解

    空指針(Null Pointer Exception,NPE)是Java中最常見不過的異常了,其原因雖然顯而易見,但是開發(fā)人員往往會忽略,或未能及時采取措施,下面這篇文章主要給大家介紹了關于Java中空指針異常該如何避免的相關資料,需要的朋友可以參考下
    2022-03-03
  • springmvc模式的上傳和下載實現(xiàn)解析

    springmvc模式的上傳和下載實現(xiàn)解析

    這篇文章主要介紹了springmvc模式下的上傳和下載實現(xiàn)解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-11-11
  • Java中如何快速構建項目腳手架的實現(xiàn)

    Java中如何快速構建項目腳手架的實現(xiàn)

    這篇文章主要介紹了Java中如何快速構建項目腳手架,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • java實現(xiàn)Redisson的基本使用

    java實現(xiàn)Redisson的基本使用

    Redisson是一個在Redis的基礎上實現(xiàn)的Java駐內存數(shù)據(jù)網(wǎng)格客戶端,本文主要介紹了java實現(xiàn)Redisson的基本使用,具有一定的參考價值,感興趣的可以了解一下
    2023-12-12
  • Spring中使用自定義ThreadLocal存儲導致的坑及解決

    Spring中使用自定義ThreadLocal存儲導致的坑及解決

    這篇文章主要介紹了Spring中使用自定義ThreadLocal存儲導致的坑及解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • 二叉樹遞歸迭代及morris層序前中后序遍歷詳解

    二叉樹遞歸迭代及morris層序前中后序遍歷詳解

    這篇文章主要為大家介紹了二叉樹遞歸迭代詳解及二叉樹的morris遍歷、層序遍歷、前序遍歷、中序遍歷、后序遍歷示例分析,有需要的朋友可以借鑒參考下
    2021-11-11

最新評論