如何实现异步方法调用,不少人首先会想到使用线程或者线程池技术,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"; }