概述

如何实现异步方法调用,很多人首先会想到使用线程或者线程池技术,springboot中有一个很简单的方法可以实现异步方法调用,那就是在方法上使用@Async注解

例子

首先在Springboot启动类上添加@EnableAsync注解,表明使用@Async注解

@SpringBootApplication
@EnableAsync
public class Application{ public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

异步调用测试类

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);
}
}

通过一个简单的接口测试即可

/**
* 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 "";
}
}

结果如下:

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注解

使用@Async注解的方法返回值为java.util.concurrent.Future 的实现类 org.springframework.scheduling.annotation.AsyncResult 类型,代码如下:

/**
* 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";
}

最新文章

  1. Struts2之文件上传下载
  2. 最火的.NET开源项目
  3. SharePoint2010安装文档
  4. Android---优化下载让网络访问更高效(三)
  5. Jquery实现日期格式化
  6. extjs tree check 级联选择
  7. LinkList Operation
  8. 在sublime_text3中实现项目的跳转
  9. CATranstion动画
  10. JS中Object常用的一些属性和方法
  11. swift之函数式编程(三)
  12. 聚类——GAKFCM
  13. vue中的axios
  14. Linux下使用bind,epoll对网络编程封装
  15. CodeForces 682A
  16. Delphi调用DLL中的接口
  17. Form_Form Builder的常用方法(概念)
  18. MySQL 备份数据库
  19. tableau-基本函数
  20. ssh远程执行命令使用明文密码

热门文章

  1. 网络流Dinic--模板
  2. dedecms发布文章时间显示多少分钟前
  3. 嵌入式linux第一阶段笔记
  4. VS2017生成一个简单的DLL文件 和 LIB文件——C语言
  5. 一个复杂关联的sql
  6. MyBatis 源码篇-Transaction
  7. 怎样理解 display:none 和 visibility:hidden
  8. mysql5.7 密码字段名更改
  9. 学习前端 第一天之html标签补充
  10. 关于写SQL语句的技巧