概述

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

例子

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

  1. @SpringBootApplication
  2. @EnableAsync
  3. public class Application{
  4. public static void main(String[] args) {
  5. SpringApplication.run(Application.class, args);
  6. }
  7. }

异步调用测试类

  1. package com.example.mongo_demo.test;
  2. import org.slf4j.Logger;
  3. import org.slf4j.LoggerFactory;
  4. import org.springframework.scheduling.annotation.Async;
  5. import org.springframework.stereotype.Component;
  6. /**
  7. * created by qinming on 2018/5/17
  8. **/
  9. @Component
  10. public class AsyncTest {
  11. public static final Logger LOGGER = LoggerFactory.getLogger(AsyncTest.class);
  12. @Async
  13. public void asyn1() throws InterruptedException {
  14. Long timeMilles = System.currentTimeMillis();
  15. Thread.sleep(7000);
  16. LOGGER.error("》》》》》》》》》》》》asyn1耗时:{}《《《《《《《《《",System.currentTimeMillis()-timeMilles);
  17. }
  18. @Async
  19. public void asyn2() throws InterruptedException {
  20. Long timeMilles = System.currentTimeMillis();
  21. Thread.sleep(7000);
  22. LOGGER.error("》》》》》》》》》》》》asyn2耗时:{}《《《《《《《《《",System.currentTimeMillis()-timeMilles);
  23. }
  24. @Async
  25. public void asyn3() throws InterruptedException {
  26. Long timeMilles = System.currentTimeMillis();
  27. Thread.sleep(10000);
  28. LOGGER.error("》》》》》》》》》》》》asyn3耗时:{}《《《《《《《《《",System.currentTimeMillis()-timeMilles);
  29. }
  30. }

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

  1. /**
  2. * created by qinming on 2018/5/17
  3. **/
  4. @RestController
  5. @RequestMapping("/api")
  6. public class DemostrationController {
  7. @Autowired
  8. private AsyncTest asyncTest;
  9. public static final Logger LOGGER = LoggerFactory.getLogger(DemostrationController.class);
  10. @RequestMapping("/async/test")
  11. public String get() throws InterruptedException {
  12. long timeMillis = System.currentTimeMillis();
  13. asyncTest.asyn1();
  14. asyncTest.asyn2();
  15. asyncTest.asyn3();
  16. Thread.sleep(1000);
  17. LOGGER.error("//////耗时:{}",System.currentTimeMillis()-timeMillis);
  18. return "";
  19. }
  20. }

结果如下:

  1. 2018-05-17 14:27:40.252 ERROR 7843 --- [nio-8080-exec-1] c.e.m.ctrl.DemostrationController : //////耗时:1019
  2. 2018-05-17 14:27:46.253 ERROR 7843 --- [cTaskExecutor-1] com.example.mongo_demo.test.AsyncTest : 》》》》》》》》》》》》asyn1耗时:7003《《《《《《《《《
  3. 2018-05-17 14:27:46.255 ERROR 7843 --- [cTaskExecutor-2] com.example.mongo_demo.test.AsyncTest : 》》》》》》》》》》》》asyn2耗时:7005《《《《《《《《《
  4. 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 类型,代码如下:

  1. /**
  2. * created by qinming on 2018/5/17
  3. **/
  4. @Component
  5. public class AsyncWIthReturnValueTest {
  6. public static final Logger LOGGER = LoggerFactory.getLogger(AsyncWIthReturnValueTest.class);
  7. @Async
  8. public Future<String> aysnc1() throws InterruptedException {
  9. Long st = System.currentTimeMillis();
  10. LOGGER.error(">>>>>>>aysnc1 start at {}>>>>>",st);
  11. Thread.sleep(7000);
  12. long end =System.currentTimeMillis();
  13. LOGGER.error(">>>>>>>aysnc1 cost :{}>>>>>",end - st);
  14. return new AsyncResult<String>("aysnc1 is done");
  15. }
  16. @Async
  17. public Future<String> aysnc2() throws InterruptedException {
  18. Long st = System.currentTimeMillis();
  19. LOGGER.error(">>>>>>>aysnc2 start at {}>>>>>",st);
  20. Thread.sleep(7000);
  21. long end =System.currentTimeMillis();
  22. LOGGER.error(">>>>>>>aysnc2 cost :{}>>>>>",end - st);
  23. return new AsyncResult<String>("aysnc2 is done");
  24. }
  25. @Async
  26. public Future<String> aysnc3() throws InterruptedException {
  27. Long st = System.currentTimeMillis();
  28. LOGGER.error(">>>>>>>aysnc3 start at {}>>>>>",st);
  29. Thread.sleep(7000);
  30. long end =System.currentTimeMillis();
  31. LOGGER.error(">>>>>>>aysnc3 cost :{}>>>>>",end - st);
  32. return new AsyncResult<String>("aysnc3 is done");
  33. }
  34. }

调用方法例子如下:

  1. @RequestMapping("/async/test")
  2. public String get() throws InterruptedException, ExecutionException {
  3. long timeMillis = System.currentTimeMillis();
  4. Future<String> async1 = asyncWIthReturnValueTest.aysnc1();
  5. Future<String> async2 = asyncWIthReturnValueTest.aysnc2();
  6. Future<String> async3 = asyncWIthReturnValueTest.aysnc3();
  7. while (true) {
  8. if (async1.isDone()){
  9. LOGGER.error("----{}1-------",async1.get());
  10. }
  11. if (async2.isDone()){
  12. LOGGER.error("----{}2-------",async2.get());
  13. }
  14. if (async3.isDone()){
  15. LOGGER.error("----{}3-------",async3.get());
  16. }
  17. if (async1.isDone() && async2.isDone() && async3.isDone()) {
  18. break;
  19. }
  20. Thread.sleep(1000);
  21. }
  22. LOGGER.error("//////耗时:{}",System.currentTimeMillis()-timeMillis);
  23. return "SUCCESS";
  24. }

spring@Async注解实现异步方法调用的更多相关文章

  1. 使用Spring中@Async注解实现异步调用

    异步调用? 在解释异步调用之前,我们先来看同步调用的定义:同步就是整个处理过程顺序执行,当各个过程都执行完毕,并返回结果. 异步调用则是只是发送了调用的指令,调用者无需等待被调用的方法完全执行完毕,继 ...

  2. 异步任务spring @Async注解源码解析

    1.引子 开启异步任务使用方法: 1).方法上加@Async注解 2).启动类或者配置类上@EnableAsync 2.源码解析 虽然spring5已经出来了,但是我们还是使用的spring4,本文就 ...

  3. (转)spring boot注解 --@EnableAsync 异步调用

    原文:http://www.cnblogs.com/azhqiang/p/5609615.html EnableAsync注解的意思是可以异步执行,就是开启多线程的意思.可以标注在方法.类上. @Co ...

  4. spring boot注解 --@EnableAsync 异步调用

    EnableAsync注解的意思是可以异步执行,就是开启多线程的意思.可以标注在方法.类上. @Component public class Task { @Async public void doT ...

  5. Spring —— @Async注解的使用

    参考文档 Spring Boot使用@Async实现异步调用:自定义线程池 Spring Boot使用@Async实现异步调用:ThreadPoolTaskScheduler线程池的优雅关闭

  6. springboot(整合多数据源demo,aop,定时任务,异步方法调用,以及获取properties中自定义的变量值)

    有这么一个需求 每个部门,需要操作的数据库不同,A部门要将数据放test数据库,B 部门数据 要放在test1数据库 同一个项目 需要整合 多个数据源 上传个demo 方便自己以后回看!!!!!!!! ...

  7. Spring @Async的异常处理

    楼主在前面的2篇文章中,分别介绍了Java子线程中通用的异常处理,以及Spring web应用中的异常处理.链接如下: Java子线程中的异常处理(通用) Spring web引用中的异常处理 今天, ...

  8. SpringCloud 微服务中 @Async 注解自定义线程池 引发的aop 问题

    背景 在 使用springCloud 的@Async注解来做异步操作时,想自定义其线程池. 引发问题 自定义完线程池后,发现代码里并没有使用自定义线程池里的线程,于是新建一个demo工程,一样的配置代 ...

  9. Spring中@Async注解实现“方法”的异步调用

    原文:http://www.cnblogs.com/zhengbin/p/6104502.html 简单介绍: Spring为任务调度与异步方法执行提供了注解支持.通过在方法上设置@Async注解,可 ...

随机推荐

  1. 【AtCoder】ARC066

    ARC066 C - Lining Up 判断是否合法即可,合法是\(2^{\lfloor \frac{N}{2}\rfloor}\) 不合法就是0 #include <bits/stdc++. ...

  2. fiddler笔记:web session窗口介绍

    1.web session列表的含义:(从左到右) # fiddler通过session生成的ID. Result 响应状态码. Host 接收请求的服务器的主机名和端口号. URL 请求资源的位置. ...

  3. 搭建 python 3.5+pycharm 2017.1.3+django 1.12.0 首次 将sqlite3 迁移到mysql

  4. python 基础例子 双色球 查询天气 查询电话

    # 随机生成双色球import random# 随机数 1-16之间# r = random.randint(1,16)# print(r)phone_numbers_str = "匪警[1 ...

  5. shell习题第14题:

    [题目要求] 需求,根据web服务器的访问日志,把一些请求高的ip给拒绝掉,并且每隔半小时把不再发起请求或者请求量很小的ip给解封 假设: 1. 一分钟内请求量高于100次的ip视为不正常的请求 2. ...

  6. Django ORM相关的一些操作

    一般操作 看专业的官网文档,做专业的程序员! 必知必会13条 <1> all(): 查询所有结果 <2> filter(**kwargs): 它包含了与所给筛选条件相匹配的对象 ...

  7. Sql Server 收缩日志文件原理及always on 下的实践

    一.准备知识 1.LSN LSN用来标识特定日志在日志文件中位置(详情请见什么是LSN:日志序列号),它由两部分组成:一部分用来标识VLF(虚拟日志文件)的序列号,剩下的用来标识该日志在VLF中的具体 ...

  8. 阿里云=>RHSA-2019:1884-中危: libssh2 安全更新

    由于项目构建时间比较长,近期安全检查发现openssh有漏洞.所以要升级openssh到7.9p1版本.由于ssh用于远程连接,所以要谨慎操作. 建议生成环境要先做测试,之后再在生产环境升级. 1 前 ...

  9. Docker本地镜像发布到阿里云和从阿里云拉取镜像

    登录阿里云官网,找到容器镜像服务 进入镜像仓库,创建仓库 输入信息 选择本地仓库 这里我要将这个镜像提交到仓库 回到仓库列表,点击管理 docker login --username=cn丶moti ...

  10. 【Distributed】分布式Session一致性问题

    一.概述 1.1 什么是Session 1.2 Session实现原理 1.3 Session常见问题 Session 保证在那里? 关闭浏览器Session会失效吗 服务器集群之后,Session产 ...