概述

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

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. 2.1spring cloud 环境配置

    前提:SpringBoot可以离开SpringCloud独立使用开发项目,但是SpringCloud离不开SpringBoot,属于依赖的关系. 所以基本是搭建SpringBoot + 组件 = Sp ...

  2. ros msg和srv使用

    在包文件中新建文件夹srv和msg,在这两个文件夹中新建test.msg,test.srv 修改apckage.xml 添加以下内容 <build_depend>:message_gene ...

  3. sklearn数据集

    数据集划分: 机器学习一般的数据集会划分为两个部分 训练数据: 用于训练,构建模型 测试数据: 在模型检验时使用,用于评估模型是否有效 sklearn数据集划分API: 代码示例文末! scikit- ...

  4. hdu 2609 字符串最小表示法 虽然不是很懂 还是先贴上来吧。/,。/

    还需要再消化一下这个算法.. 今天没有时间了,, 六级过了 就有大把时间 快活啊!#include<iostream> #include<cstdio> #include< ...

  5. C#连接Oracle数据库的方法

    目前了解C#中连接Oracle数据库的方法有3种,分布是微软的System.Data.OracleClient,Oracle的Oracle.DataAccess.Client和Oracle的Oracl ...

  6. 3、详解 ESLint 规则 转自https://blog.csdn.net/bbsyi/article/details/88816637

    什么是 ESLint ? ESLint 是在 ECMAScript/JavaScript 代码中识别和报告模式匹配的工具,它的目标是保证代码的一致性和避免错误.在许多方面,它和 JSLint.JSHi ...

  7. python selenium5 模拟点击+拖动+按照指定相对坐标拖动 58同城验证码

    #!/usr/bin/python # -*- coding: UTF-8 -*- # @Time : 2019年12月9日11:41:08 # @Author : shenghao/10347899 ...

  8. 题解 P3369 【【模板】普通平衡树(Treap/SBT)】

    STL真是个好东西. 最近在看pb_ds库及vector和set的用法,就想用这三种操作来实现一下普通平衡树,结果pb_ds中的rbtree不支持重复值,而本蒟蒻也看不懂不懂各大佬用pb_ds的实现, ...

  9. 在Android8.0以上收不到广播问题(AppWidget)

    对Intent指定组件 //安卓8.0必须添加 intent.setComponent(new ComponentName(context,MyAppWidgetProvider.class)); 问 ...

  10. kubernetes之Taints污点和Tolerations容忍

    介绍说明 nodeaffinity节点亲和性是pod上定义的一种属性, 使得pod能够被调度到某些node上运行, taint污点正好相反, 它让node拒绝pod运行, 除非pod明确声明能够容忍这 ...