@Async实现异步调用

pom.xml

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

启动类

@EnableAsync
@SpringBootApplication
public class LearnutilsApplication { public static void main(String[] args) {
SpringApplication.run(LearnutilsApplication.class, args);
} /**
* 核心线程数10:线程池创建时初始化的线程数
* 最大线程数20:线程池最大的线程数,只有在缓冲队列满了之后才会申请超过核心线程数的线程
* 缓冲队列200:用来缓冲执行任务的队列
* 允许线程的空闲时间60秒:超过了核心线程数之外的线程,在空闲时间到达之后会被销毁
* 线程池名的前缀:设置好了之后可以方便我们定位处理任务所在的线程池
* 线程池对拒绝任务的处理策略:此处采用了CallerRunsPolicy策略,当线程池没有处理能力的时候,该策略会直接在execute方法的调用线程中运行被拒绝的任务;如果执行程序已被关闭,则会丢弃该任务
* 设置线程池关闭的时候等待所有任务都完成再继续销毁其他的Bean
* 设置线程池中任务的等待时间,如果超过这个时候还没有销毁就强制销毁,以确保应用最后能够被关闭,而不是阻塞住
*/
@EnableAsync
@Configuration
class TaskPoolConfig{
@Bean("taskExecutor")
public Executor taskExecutor(){
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(20);
executor.setQueueCapacity(200);
executor.setKeepAliveSeconds(60);
executor.setThreadNamePrefix("TaskExecutor-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.setAwaitTerminationSeconds(60);
return executor;
}
} }

定义controller

@RequestMapping(value = "/AsyncController")
@RestController
public class AsyncController { @Autowired
private AsyncService asyncService; @Autowired
private AsyncService2 asyncService2; @Autowired
private AsyncService3 asyncService3; @GetMapping(value = "/sendSms")
public String sendSms() throws Exception{
 
Future<String> sms = asyncService.sendSms();
Future<String> sms2 = asyncService2.sendSms();
Future<String> sms3 = asyncService3.sendSms();
int i = 0;
for (;;) {
//如果都执行完就跳出循环,isDone方法,如果此线程执行完,true
if (sms.isDone() && sms2.isDone() && sms3.isDone()) {
break;
}
}
//get是获取结果集
return sms.get()+sms2.get()+sms3.get();
}
}

定义接口

public interface AsyncService {
Future<String> sendSms();
}

实现类

@Service
public class AsyncServiceImpl implements AsyncService {
//Future<String> 返回结果 AsyncResult<String>
@Async("taskExecutor")
@Override
public Future<String> sendSms() {
return new AsyncResult<>("000000");
}
}

将isDone换程CountDownLatch来判断线程是否执行完实例化CountDownLatch并且制定线程个数,线程个数就是从本地异步调用的方法个输,并且传入线程任务中,每个线程执行完毕就调用countDown()方法。最后在调用await()方法。这样在线程计数为零之前,线程就会一直等待。

AsyncResult用来封装结果集,否则结果集无法返回

@GetMapping(value = "/sendSms2")
public String sendSms2() throws Exception{
CountDownLatch downLatch = new CountDownLatch(3);
Future<String> s = asyncService4.sendSms(downLatch);
Future<String> s1 = asyncService5.sendSms(downLatch);
Future<String> s2 = asyncService6.sendSms(downLatch);
downLatch.await();
return s.get()+s1.get()+s2.get();
}

将CountDownLatch传给方法

public interface AsyncService4 {
Future<String> sendSms(CountDownLatch downLatch);
}

方法

@Service
public class AsyncService4Impl implements AsyncService4 { @Async("taskExecutor")
@Override
public Future<String> sendSms(CountDownLatch downLatch) {
downLatch.countDown();
return new AsyncResult<>("11111");
}
}

TaskExecutor的使用

注册TaskExecutor

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import java.util.concurrent.ThreadPoolExecutor; /**
* @author yanjun
* @date 2019/8/1 16:04
**/
@Configuration
public class MainConfiguration {
@Bean
public TaskExecutor getTaskExecutor(){
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// 设置核心线程数
executor.setCorePoolSize(5);
// 设置最大线程数
executor.setMaxPoolSize(10);
// 设置队列容量
executor.setQueueCapacity(20);
// 设置线程活跃时间(秒)
executor.setKeepAliveSeconds(60);
// 设置默认线程名称
executor.setThreadNamePrefix("post-lending-");
// 设置拒绝策略
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// 等待所有任务结束后再关闭线程池
executor.setWaitForTasksToCompleteOnShutdown(true);
return executor;
}
}

使用TaskExecutor

@Autowired
private TaskExecutor taskExecutor; public ResultVO findHandlingRecordByAssociationId(Integer associationId) throws InterruptedException{
Map<String, Object> map = new HashMap<>(2);
//线程计数器(等待所有线程执行完统一返回)
CountDownLatch countDownLatch = new CountDownLatch(10);
taskExecutor.execute(() -> {
try {
//service调用
map.put("HandlingRecord", legalLitigationService.findHandlingRecordByAssociationId(associationId));
}finally {
countDownLatch.countDown();
}
});
taskExecutor.execute(() -> {
try {
map.put("CaseBasic", legalLitigationService.findCaseDetailsById(associationId));
}finally {
countDownLatch.countDown();
}
});
countDownLatch.await();
return ResultVO.putSuccess(map);
}

springboot多线程TaskExecutor的使用,以及使用@Async实现异步调用的更多相关文章

  1. spring boot 学习(十一)使用@Async实现异步调用

    使用@Async实现异步调用 什么是”异步调用”与”同步调用” “同步调用”就是程序按照一定的顺序依次执行,,每一行程序代码必须等上一行代码执行完毕才能执行:”异步调用”则是只要上一行代码执行,无需等 ...

  2. Spring Boot使用@Async实现异步调用

    原文:http://blog.csdn.net/a286352250/article/details/53157822 项目GitHub地址 : https://github.com/FrameRes ...

  3. spring boot中使用@Async实现异步调用任务

    本篇文章主要介绍了spring boot中使用@Async实现异步调用任务,小编觉得挺不错的,现在分享给大家,也给大家做个参考.一起跟随小编过来看看吧 什么是“异步调用”? “异步调用”对应的是“同步 ...

  4. SpringBoot使用@Async实现异步调用

    1.@EnableAsync 首先,我们需要在启动类上添加  @EnableAsync 注解来声明开启异步方法. @SpringBootApplication @EnableAsync public ...

  5. 注解@Async解决异步调用问题

    序言:Spring中@Async 根据Spring的文档说明,默认采用的是单线程的模式的.所以在Java应用中,绝大多数情况下都是通过同步的方式来实现交互处理的. 那么当多个任务的执行势必会相互影响. ...

  6. Spring Boot使用@Async实现异步调用:自定义线程池

    前面的章节中,我们介绍了使用@Async注解来实现异步调用,但是,对于这些异步执行的控制是我们保障自身应用健康的基本技能.本文我们就来学习一下,如果通过自定义线程池的方式来控制异步调用的并发. 定义线 ...

  7. Spring Boot2.0之@Async实现异步调用

    补充一个知识点: lombok底层原理使用的是: 字节码技术ASM修改字节码文件,生成比如类似于get() set( )方法 一定要在开发工具安装 在编译时候修改字节码文件(底层使用字节码技术),线上 ...

  8. 56. spring boot中使用@Async实现异步调用【从零开始学Spring Boot】

    什么是"异步调用"? "异步调用"对应的是"同步调用",同步调用指程序按照定义顺序依次执行,每一行程序都必须等待上一行程序执行完成之后才能执 ...

  9. Spring @Async实现异步调用示例

    什么是“异步调用”? “异步调用”对应的是“同步调用”,同步调用指程序按照定义顺序依次执行,每一行程序都必须等待上一行程序执行完成之后才能执行:异步调用指程序在顺序执行时,不等待异步调用的语句返回结果 ...

  10. Spring Boot中使用@Async实现异步调用

    在Spring Boot中,我们只需要通过使用@Async注解就能简单的将原来的同步函数变为异步函数,为了让@Async注解能够生效,还需要在Spring Boot的主程序中配置@EnableAsyn ...

随机推荐

  1. [官方]Beyond Compare里面 二进制比较的含义.

    Content Comparisons Actions > Compare Contents In the Actions menu, the Compare Contents command ...

  2. 开源项目01--WTM

    一.项目名称:WTM 项目所用技术栈: wtm mvvm mvc aspnetcore dotnetcore react vue layui layui-admin element-ui ncc等 项 ...

  3. 从零开始配置vim(31)——git 配置

    很抱歉又拖更了这么久了,在这个新公司我想快速度过试用期,所以大部分的精力主要花在日常工作上面.但是这个系列还是得更新下去,平时只能抽有限的业余时间来准备.这就导致我写这些文章就慢了一些. 废话不多说, ...

  4. 【8】python_matplotlib改变横坐标和纵坐标上的刻度(ticks)、sagemath-list_plot()调整图例(legend)中点的数量、Matplotlib画各种论文图

    1.python_matplotlib改变横坐标和纵坐标上的刻度(ticks) 用matplotlib画二维图像时,默认情况下的横坐标和纵坐标显示的值有时达不到自己的需求,需要借助xticks()和y ...

  5. Python 实现ARP扫描与欺骗

    ARP欺骗又称ARP毒化或ARP攻击,是针对以太网地址解析协议ARP的一种攻击技术,通过欺骗局域网内访问者PC的网关MAC地址,使访问者PC错以为攻击者更改后的MAC地址是网关的MAC,导致网络不通. ...

  6. 太强了!本地存档一键导入 Sealos 帕鲁专属服务器

    上一篇:幻兽帕鲁 Palworld 私有服务器一键部署教程 作为一名资深帕鲁,我的职责就是帮助各位帕鲁主人们闭着眼睛部署私服,完全不用带脑子. 我就喜欢群里的帕鲁老板们压榨我,拿鞭子抽我让我赶紧上新功 ...

  7. 深入剖析Java中的反射,由浅入深,层层剥离!

    写在开头 之前更新了不少Java的基础知识,比如Java的类.对象.基础类型.关键字.序列化.泛型.值传递等等,今天要上点深度了,来聊一聊Java中的 反射 ! 所谓反射,就是在运行时分析.检查和操作 ...

  8. P10114 [LMXOI Round 1] Size 题解

    题目链接:[LMXOI Round 1] Size 挺有意思的诈骗题,其实这类题都喜欢批一个外壳,例如数据范围提示之类的.记得以前遇到的很多诈骗题,有一道 cf 的高分题,问的是区间出现次数的次数 \ ...

  9. docker 安装的jenkins如何执行宿主机的shell启动jar包

    最近在用docker做自动化部署的时候遇到一个问题,就是用docker装的jenkins可以通过映射执行宿主机脚本.但是,却无法通过shell脚本启动宿主机jar包.经排查最终用以下方案完美解决. 一 ...

  10. Oracle私网mtu滚动修改实施方案

    之前测试遇到过mtu修改不能滚动的情况,目前在自己测试环境重新反复验证发现正常是可以滚动的,下面梳理下整个实施方案: 环境:RHEL6 + Oracle 11.2.0.4 RAC(2 nodes) / ...