如何實現異步方法調用,不少人首先會想到使用線程或者線程池技術,springboot中有一個很簡單的方法能夠實現異步方法調用,那就是在方法上使用@Async註解java
首先在Springboot啓動類上添加@EnableAsync註解,代表使用@Async註解spring
@SpringBootApplication @EnableAsync public class Application{ public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
異步調用測試類api
package com.example.mongo_demo.test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; /** * created by qinming on 2018/5/17 **/ @Component public class AsyncTest { public static final Logger LOGGER = LoggerFactory.getLogger(AsyncTest.class); @Async public void asyn1() throws InterruptedException { Long timeMilles = System.currentTimeMillis(); Thread.sleep(7000); LOGGER.error("》》》》》》》》》》》》asyn1耗時:{}《《《《《《《《《",System.currentTimeMillis()-timeMilles); } @Async public void asyn2() throws InterruptedException { Long timeMilles = System.currentTimeMillis(); Thread.sleep(7000); LOGGER.error("》》》》》》》》》》》》asyn2耗時:{}《《《《《《《《《",System.currentTimeMillis()-timeMilles); } @Async public void asyn3() throws InterruptedException { Long timeMilles = System.currentTimeMillis(); Thread.sleep(10000); LOGGER.error("》》》》》》》》》》》》asyn3耗時:{}《《《《《《《《《",System.currentTimeMillis()-timeMilles); } }
經過一個簡單的接口測試便可springboot
/** * created by qinming on 2018/5/17 **/ @RestController @RequestMapping("/api") public class DemostrationController { @Autowired private AsyncTest asyncTest; public static final Logger LOGGER = LoggerFactory.getLogger(DemostrationController.class); @RequestMapping("/async/test") public String get() throws InterruptedException { long timeMillis = System.currentTimeMillis(); asyncTest.asyn1(); asyncTest.asyn2(); asyncTest.asyn3(); Thread.sleep(1000); LOGGER.error("//////耗時:{}",System.currentTimeMillis()-timeMillis); return ""; } }
結果以下:app
2018-05-17 14:27:40.252 ERROR 7843 --- [nio-8080-exec-1] c.e.m.ctrl.DemostrationController : //////耗時:1019 2018-05-17 14:27:46.253 ERROR 7843 --- [cTaskExecutor-1] com.example.mongo_demo.test.AsyncTest : 》》》》》》》》》》》》asyn1耗時:7003《《《《《《《《《 2018-05-17 14:27:46.255 ERROR 7843 --- [cTaskExecutor-2] com.example.mongo_demo.test.AsyncTest : 》》》》》》》》》》》》asyn2耗時:7005《《《《《《《《《 2018-05-17 14:27:49.254 ERROR 7843 --- [cTaskExecutor-3] com.example.mongo_demo.test.AsyncTest : 》》》》》》》》》》》》asyn3耗時:10004《《《《《《《《《
這樣就實現了異步方法的簡單調用異步
使用@Async註解的方法返回值爲java.util.concurrent.Future 的實現類 org.springframework.scheduling.annotation.AsyncResult 類型,代碼以下:async
/** * created by qinming on 2018/5/17 **/ @Component public class AsyncWIthReturnValueTest { public static final Logger LOGGER = LoggerFactory.getLogger(AsyncWIthReturnValueTest.class); @Async public Future<String> aysnc1() throws InterruptedException { Long st = System.currentTimeMillis(); LOGGER.error(">>>>>>>aysnc1 start at {}>>>>>",st); Thread.sleep(7000); long end =System.currentTimeMillis(); LOGGER.error(">>>>>>>aysnc1 cost :{}>>>>>",end - st); return new AsyncResult<String>("aysnc1 is done"); } @Async public Future<String> aysnc2() throws InterruptedException { Long st = System.currentTimeMillis(); LOGGER.error(">>>>>>>aysnc2 start at {}>>>>>",st); Thread.sleep(7000); long end =System.currentTimeMillis(); LOGGER.error(">>>>>>>aysnc2 cost :{}>>>>>",end - st); return new AsyncResult<String>("aysnc2 is done"); } @Async public Future<String> aysnc3() throws InterruptedException { Long st = System.currentTimeMillis(); LOGGER.error(">>>>>>>aysnc3 start at {}>>>>>",st); Thread.sleep(7000); long end =System.currentTimeMillis(); LOGGER.error(">>>>>>>aysnc3 cost :{}>>>>>",end - st); return new AsyncResult<String>("aysnc3 is done"); } }
調用方法例子以下:測試
@RequestMapping("/async/test") public String get() throws InterruptedException, ExecutionException { long timeMillis = System.currentTimeMillis(); Future<String> async1 = asyncWIthReturnValueTest.aysnc1(); Future<String> async2 = asyncWIthReturnValueTest.aysnc2(); Future<String> async3 = asyncWIthReturnValueTest.aysnc3(); while (true) { if (async1.isDone()){ LOGGER.error("----{}1-------",async1.get()); } if (async2.isDone()){ LOGGER.error("----{}2-------",async2.get()); } if (async3.isDone()){ LOGGER.error("----{}3-------",async3.get()); } if (async1.isDone() && async2.isDone() && async3.isDone()) { break; } Thread.sleep(1000); } LOGGER.error("//////耗時:{}",System.currentTimeMillis()-timeMillis); return "SUCCESS"; }