在Spring Boot中,我們只需要通過使用@Async
注解就能簡單的將原來的同步函數變為異步函數,為了讓@Async注解能夠生效,還需要在Spring Boot的主程序中配置@EnableAsync。實例如下:
創建Task類,Task里面包含三個方法,分別是:doTaskOne,doTaskTwo,doTaskThree
@Component public class Task { private static Random random = new Random(); @Async public void doTaskOne() throws Exception { System.out.println("開始做任務一"); long start = System.currentTimeMillis(); Thread.sleep(random.nextInt(10000)); long end = System.currentTimeMillis(); System.out.println("完成任務一,耗時:" + (end - start) + "毫秒"); } @Async public void doTaskTwo() throws Exception { System.out.println("開始做任務二"); long start = System.currentTimeMillis(); Thread.sleep(random.nextInt(10000)); long end = System.currentTimeMillis(); System.out.println("完成任務二,耗時:" + (end - start) + "毫秒"); } @Async public void doTaskThree() throws Exception { System.out.println("開始做任務三"); long start = System.currentTimeMillis(); Thread.sleep(random.nextInt(10000)); long end = System.currentTimeMillis(); System.out.println("完成任務三,耗時:" + (end - start) + "毫秒"); } }
@SpringBootApplication @EnableScheduling @EnableAsync public class Application { public static void main(String[] args){ SpringApplication.run(Application.class,args); } }
值得注意的是:@Async所修飾的函數不要定義為static類型,這樣異步調用不會生效
異步回調
為了讓doTaskOne
、doTaskTwo
、doTaskThree
能正常結束,假設我們需要統計一下三個任務並發執行共耗時多少,這就需要等到上述三個函數都完成調動之后記錄時間,並計算結果。那么我們如何判斷上述三個異步調用是否已經執行完成呢?我們需要使用Future<T>
來返回異步調用的結果,就像如下方式改造doTaskOne
函數:
@Async public Future<String> doTaskOne() throws Exception { System.out.println("開始做任務一"); long start = System.currentTimeMillis(); Thread.sleep(random.nextInt(10000)); long end = System.currentTimeMillis(); System.out.println("完成任務一,耗時:" + (end - start) + "毫秒"); return new AsyncResult<>("任務完成"); }
按照上述方式改造其他的函數,測試代碼如下:
@Test public void test() throws Exception { long start = System.currentTimeMillis(); Future<String> task1 = task.doTaskOne(); Future<String> task2 = task.doTaskTwo(); Future<String> task3 = task.doTaskThree(); while(true) { if(task1.isDone() && task2.isDone() && task3.isDone()) { // 三個任務都調用完成,退出循環等待 break; } Thread.sleep(1000); } long end = System.currentTimeMillis(); System.out.println("任務全部完成,總耗時:" + (end - start) + "毫秒"); }