@Async源码探究
1. @Async源码探究
1.1. 上代码
@SpringBootApplication
@EnableAsync
public class SpringbootLearnApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootLearnApplication.class, args);
}
}
@Service
public class CreatingThread08Service {
@Async
public void call(CountDownLatch countDownLatch) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " is running");
countDownLatch.countDown();
System.out.println(Thread.currentThread().getName() + " is over");
}
}
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootLearnApplicationTests {
@Autowired
private CreatingThread08Service creatingThread08Service;
private int count = 4;
private CountDownLatch countDownLatch = new CountDownLatch(count);
@Test
public void contextLoads() {
StopWatch stopwatch = new StopWatch("async test");
stopwatch.start();
for (int i = 0; i < count; i++) {
creatingThread08Service.call(countDownLatch);
}
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
stopwatch.stop();
System.out.println(stopwatch.prettyPrint());
}
}
结果
task-2 is running
task-2 is over
task-4 is running
task-4 is over
task-1 is running
task-1 is over
task-3 is running
task-3 is over
StopWatch 'async test': running time (millis) = 1018
-----------------------------------------
ms % Task name
-----------------------------------------
01018 100%
1.2. 提问
1.2.1. 加了该注解的方法,如果同时被调用n次,难道会创建n个线程?
通过debugger源码找到如下信息,为它默认线程池设置属性

我们把运行数量加大到
count=20结果
task-1 is running
task-1 is over
task-8 is running
task-8 is over
task-5 is running
task-5 is over
task-3 is running
task-3 is over
task-4 is running
task-4 is over
task-7 is running
task-7 is over
task-2 is running
task-2 is over
task-6 is running
task-6 is over
task-1 is running
task-1 is over
task-8 is running
task-3 is running
task-3 is over
task-5 is running
task-5 is over
task-8 is over
task-4 is running
task-6 is running
task-6 is over
task-7 is running
task-7 is over
task-2 is running
task-2 is over
task-4 is over
task-5 is running
task-1 is running
task-8 is running
task-8 is over
task-1 is over
task-3 is running
task-3 is over
task-5 is over
StopWatch 'async test': running time (millis) = 3021
-----------------------------------------
ms % Task name
-----------------------------------------
03021 100%
- 可以看出,如截图一致,它的运行核心执行线程数为8,且队列数很大,所以几乎不会再创建新的线程数,我特意sleep了1秒,20个任务,足够该线程池运行3遍,所以最大延迟3秒多
1.3. 那么核心线程数这个值能够变吗?
- 可以,通过
application.properties中修改spring.task.execution.pool.core-size=20的值,比如我现在改成20,那么打印结果如下
task-1 is running
task-9 is running
task-12 is running
task-15 is running
task-17 is running
task-11 is running
task-11 is over
task-1 is over
task-10 is running
task-10 is over
task-8 is running
task-8 is over
task-6 is running
task-6 is over
task-4 is running
task-4 is over
task-7 is running
task-7 is over
task-5 is running
task-3 is running
task-3 is over
task-20 is running
task-20 is over
task-17 is over
task-19 is running
task-19 is over
task-2 is running
task-2 is over
task-18 is running
task-18 is over
task-15 is over
task-16 is running
task-16 is over
task-12 is over
task-14 is running
task-14 is over
task-13 is running
task-13 is over
task-9 is over
task-5 is over
StopWatch 'async test': running time (millis) = 1020
-----------------------------------------
ms % Task name
-----------------------------------------
01020 100%
- 所有线程只执行一遍,最大延迟就1秒多了
1.4. 总结
- 使用该注解,会创建默认核心线程为8的线程池,它的很多属性是可以通过配置设置的,如下
spring.task.execution.pool.core-size=10
spring.task.execution.thread-name-prefix=mytask-
spring.task.execution.pool.queue-capacity=10
spring.task.execution.pool.max-size=20
spring.task.execution.pool.keep-alive=60s
spring.task.execution.pool.allow-core-thread-timeout=true
- 根据业务需求设置合理的属性值,就相当于spring给你创建了线程池了
@Async源码探究的更多相关文章
- spring-cloud-sleuth+zipkin源码探究
1. spring-cloud-sleuth+zipkin源码探究 1.1. 前言 粗略看了下spring cloud sleuth core源码,发现内容真的有点多,它支持了很多类型的链路追踪, ...
- spring-boot-2.0.3之quartz集成,数据源问题,源码探究
前言 开心一刻 着火了,他报警说:119吗,我家发生火灾了. 119问:在哪里? 他说:在我家. 119问:具体点. 他说:在我家的厨房里. 119问:我说你现在的位置. 他说:我趴在桌子底下. 11 ...
- 【转载】Spring @Async 源码解读。
由于工作中经常需要使用到异步操作,一直在使用@Async, 今天抽空学习了一下它的执行原理,刚好看到一篇写的很棒的文章,这里转载过来做个记录,感谢原作者的无私奉献. 原文章链接地址:https://w ...
- Vue源码探究-全局API
Vue源码探究-全局API 本篇代码位于vue/src/core/global-api/ Vue暴露了一些全局API来强化功能开发,API的使用示例官网上都有说明,无需多言.这里主要来看一下全局API ...
- Vue源码探究-事件系统
Vue源码探究-事件系统 本篇代码位于vue/src/core/instance/events.js 紧跟着生命周期之后的就是继续初始化事件相关的属性和方法.整个事件系统的代码相对其他模块来说非常简短 ...
- Vue源码探究-状态初始化
Vue源码探究-状态初始化 Vue源码探究-源码文件组织 Vue源码探究-虚拟DOM的渲染 本篇代码位于vue/src/core/instance/state.js 继续随着核心类的初始化展开探索其他 ...
- Vue源码探究-源码文件组织
Vue源码探究-源码文件组织 源码探究基于最新开发分支,当前发布版本为v2.5.17-beta.0 Vue 2.0版本的大整改不仅在于使用功能上的优化和调整,整个代码库也发生了天翻地覆的重组.可见随着 ...
- SpringBoot读取配置文件源码探究
1. SpringBoot读取配置文件源码探究 1.1. 概览 springboot的源码是再原来的Spring源码上又包了一层,看过spring源码都知道,当我们从入口debug进去的时候,原来的S ...
- Sharding-Jdbc源码探究-读写分离
1. Sharding-Jdbc源码探究-读写分离 1.1. 主入口 找到源码入口 这一个类围绕了springboot配置属性的加载,加载了spring.shardingsphere.datasour ...
随机推荐
- c# 第17节 二维数组声明、使用
本节内容: 1:为什么要有二维数组 2:二维数据 3:实例二维数组声明 4:二维数组的使用 1:为什么要有二维数组 2:二维数据声明 3:实例二维数组声明 4:二维数组的使用 foreach遍历 5: ...
- 201871010112-梁丽珍《面向对象程序设计(java)》第七周学习总结
项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ...
- Java8——Lambda表达式
/* * 一.Lambda 表达式的基础语法:Java8中引入了一个新的操作符 "->" 该操作符称为箭头操作符或 Lambda 操作符 * 箭头操作符将 Lambda 表达 ...
- Linux下Maven安装(十二)
一.前提条件 下载并安装好JDK .在终端输入命令“java -version”,如果出现类似如下信息说明JDK安装成功. 二.开始配置Maven 1. 下载maven:http://mirror.b ...
- Dubbo介绍(一)
Dubbo是一个分布式.高性能.透明化的 RPC 服务框架,作用是提供服务自动注册.自动发现等高效服务治理方案. 一.Dubbo架构图 Provider:提供者,服务发布方 Consumer:消费者, ...
- Spring Boot中以代码方式配置Tomcat
在Spring Boot2.0以上配置嵌入式Servlet容器时EmbeddedServletContainerCustomizer类不存在,经网络查询发现被WebServerFactoryCusto ...
- 编码-转义2-mark
文本编辑器utf8 "一".encode("gbk") 保存:"一"+utf8 保存为16进制的\xe4\xb8\x80,\x标识了 ...
- 数据结构——顺序队列(sequence queue)
/* sequenceQueue.c */ /* 顺序队列 */ #include <stdio.h> #include <stdlib.h> #include <std ...
- shell 脚本 for,while,case 语句详解及案例
################for循环语句的结构#############使用for循环语句时,需要指定一个变量及可能的取值列表,针对每个不同的取值重复执行相同的命令序列,直到变量值用完退出循环. ...
- NLP之预训练
内容是结合:https://zhuanlan.zhihu.com/p/49271699 可以直接看原文 预训练一般要从图像处理领域说起:可以先用某个训练集合比如训练集合A或者训练集合B对这个网络进行预 ...