SpringBoot 线程池配置 实现AsyncConfigurer接口方法
目的是:
通过实现AsyncConfigurer自定义线程池,包含异常处理
实现AsyncConfigurer接口对异常线程池更加细粒度的控制
*a) 创建线程自己的线程池
b) 对void方法抛出的异常处理的类AsyncUncaughtExceptionHandler
个人初步理解
一、线程池是为突然大量爆发的线程设计的,通过有限的几个固定线程为大量的操作服务,减少了创建和销毁线程所需的时间,
从而提高效率。如果一个线程的时间非常长,就没必要用线程池了(不是不能作长时间操作,而是不宜。),
况且还不能控制线程池中线程的开始、挂起、和中止。
二、利用线程池启动线程
Thread udpThread = new Thread(udp);
poolTaskExecutor.execute(udpThread);
获取当前线程池活动的线程数:
int count = poolTaskExecutor.getActiveCount();
logger.debug("[x] - now threadpool active threads totalNum : " +count);
三、配置解释
当一个任务通过execute(Runnable)方法欲添加到线程池时:
1、 如果此时线程池中的数量小于corePoolSize,即使线程池中的线程都处于空闲状态,也要创建新的线程来处理被添加的任务。
2、 如果此时线程池中的数量等于 corePoolSize,但是缓冲队列 workQueue未满,那么任务被放入缓冲队列。
3、如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量小于maximumPoolSize,建新的线程来处理被添加的任务。
4、 如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量等于maximumPoolSize,那么通过 handler所指定的策略来处理此任务。
也就是:处理任务的优先级为:核心线程corePoolSize、任务队列workQueue、最大线程 maximumPoolSize,如果三者都满了,使用handler处理被拒绝的任务。
5、 当线程池中的线程数量大于 corePoolSize时,如果某线程空闲时间超过keepAliveTime,线程将被终止。这样,线程池可以动态的调整池中的线程数。
allowCoreThreadTimeout:允许核心线程超时
rejectedExecutionHandler:任务拒绝处理器
两种情况会拒绝处理任务:
当线程数已经达到maxPoolSize,切队列已满,会拒绝新任务
当线程池被调用shutdown()后,会等待线程池里的任务执行完毕,再shutdown。如果在调用shutdown()和线程池真正shutdown之间提交任务,会拒绝新任务
线程池会调用rejectedExecutionHandler来处理这个任务。如果没有设置默认是AbortPolicy,会抛出异常
ThreadPoolExecutor类有几个内部实现类来处理这类情况:
AbortPolicy 丢弃任务,抛运行时异常
CallerRunsPolicy 执行任务
DiscardPolicy 忽视,什么都不会发生
DiscardOldestPolicy 从队列中踢出最先进入队列(最后一个执行)的任务
实现RejectedExecutionHandler接口,可自定义处理器
废话不多说 上代码 环境:IDEA +SpringBoot+maven
一、线程池配置类实现AsyncConfigurer 接口:

@Component
public class MyAsyncConfigurer implements AsyncConfigurer { private static final Logger log = LoggerFactory.getLogger(MyAsyncConfigurer.class); public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor threadPool = new ThreadPoolTaskExecutor();
threadPool.setCorePoolSize(2);//当前线程数
threadPool.setMaxPoolSize(120);// 最大线程数
threadPool.setQueueCapacity(1);//线程池所使用的缓冲队列
threadPool.setWaitForTasksToCompleteOnShutdown(true);//等待任务在关机时完成--表明等待所有线程执行完
threadPool.setAwaitTerminationSeconds(60 * 15);// 等待时间 (默认为0,此时立即停止),并没等待xx秒后强制停止
threadPool.setThreadNamePrefix("MyAsync-");// 线程名称前缀
threadPool.initialize(); // 初始化
System.out.println("--------------------------》》》开启异常线程池");
return threadPool;
} public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { return new MyAsyncExceptionHandler();
} /**
* 自定义异常处理类
* @author hry
*
*/
class MyAsyncExceptionHandler implements AsyncUncaughtExceptionHandler { //手动处理捕获的异常
@Override
public void handleUncaughtException(Throwable throwable, Method method, Object... obj) {
System.out.println("-------------》》》捕获线程异常信息");
log.info("Exception message - " + throwable.getMessage());
log.info("Method name - " + method.getName());
for (Object param : obj) {
log.info("Parameter value - " + param);
}
} }

二、使用简单无参数异步线程进行测试

@Override
@Async
public String asyncMethodWithVoidReturnType() { System.out.println("线程名称:"+Thread.currentThread().getName() + " be ready to read data!");
try {
Thread.sleep(1000 * 5);
System.out.println("---------------------》》》无返回值延迟3秒:");
} catch (InterruptedException e) {
e.printStackTrace();
}
return "已进入到异步";
}

三、0--3秒内连续访问如下结果

线程名称:MyAsync-1 be ready to read data!
线程名称:MyAsync-2 be ready to read data!
线程名称:MyAsync-3 be ready to read data!
线程名称:MyAsync-4 be ready to read data!
线程名称:MyAsync-5 be ready to read data!
线程名称:MyAsync-6 be ready to read data!
线程名称:MyAsync-7 be ready to read data!
线程名称:MyAsync-8 be ready to read data!
MyAsync-1---------------------》》》无返回值延迟5秒:
线程名称:MyAsync-1 be ready to read data!
MyAsync-2---------------------》》》无返回值延迟5秒:
线程名称:MyAsync-2 be ready to read data!
MyAsync-3---------------------》》》无返回值延迟5秒:
MyAsync-4---------------------》》》无返回值延迟5秒:
MyAsync-5---------------------》》》无返回值延迟5秒:
MyAsync-6---------------------》》》无返回值延迟5秒:
MyAsync-7---------------------》》》无返回值延迟5秒:
MyAsync-8---------------------》》》无返回值延迟5秒:
MyAsync-1---------------------》》》无返回值延迟5秒:
MyAsync-2---------------------》》》无返回值延迟5秒:

如上可以看出 线程池发挥作用 多个线程访问如果超过核心线程数+队列数 变新创建线程,如果有线程
空闲下来会继续分配,以此来提高效率。我是利用postMain 来进行的测试,以验证上面所说的理论问题。。
实际应用中比这个复杂得多。。。。。。。。
四、如果想要手动捕获异常信息 如下代码 即可
throw new IllegalArgumentException(s);
将上面代码 放在需要捕获信息的中
在线程池配置中 MyAsyncExceptionHandler 的方法中 即会捕捉到信息。。。。。。
SpringBoot 线程池配置 实现AsyncConfigurer接口方法的更多相关文章
- Springboot 线程池配置
最近的项目里要手动维护线程池,然后看到一起开发的小伙伴直接用Java了,我坚信Springboot不可能没这功能,于是查了些资料,果然有,这里给一下. 首先我们都知道@Async标签能让方法异步执行, ...
- SpringBoot异步及线程池配置
异步方法注解@Async 在SpringBoot中进行异步处理,可以使用异步注解@Async和@EnableAsync. @Async注解表示异步,如:@Async("asyncServic ...
- Spring线程池配置模板设计(基于Springboot)
目录 线程池配置模板 基础的注解解释 常用配置参数 配置类设计 线程池使用 ThreadPoolTaskExecutor源码 线程池配置模板 springboot给我们提供了一个线程池的实现,它的底层 ...
- SpringBoot线程池的创建、@Async配置步骤及注意事项
最近在做订单模块,用户购买服务类产品之后,需要进行预约,预约成功之后分别给商家和用户发送提醒短信.考虑发短信耗时的情况所以我想用异步的方法去执行,于是就在网上看见了Spring的@Async了. 但是 ...
- 玩转SpringBoot之定时任务@Scheduled线程池配置
序言 对于定时任务,在SpringBoot中只需要使用@Scheduled 这个注解就能够满足需求,它的出现也给我们带了很大的方便,我们只要加上该注解,并且根据需求设置好就可以使用定时任务了. 但是, ...
- springboot 线程池
我们常用ThreadPoolExecutor提供的线程池服务,springboot框架提供了@Async注解,帮助我们更方便的将业务逻辑提交到线程池中异步执行,今天我们就来实战体验这个线程池服务: 本 ...
- springboot线程池的使用和扩展(转)
springboot线程池的使用和扩展 我们常用ThreadPoolExecutor提供的线程池服务,springboot框架提供了@Async注解,帮助我们更方便的将业务逻辑提交到线程池中异步执行, ...
- springboot线程池的使用和扩展
我们常用ThreadPoolExecutor提供的线程池服务,springboot框架提供了@Async注解,帮助我们更方便的将业务逻辑提交到线程池中异步执行,今天我们就来实战体验这个线程池服务: 本 ...
- springboot线程池@Async的使用和扩展
我们常用ThreadPoolExecutor提供的线程池服务,springboot框架提供了@Async注解,帮助我们更方便的将业务逻辑提交到线程池中异步执行,今天我们就来实战体验这个线程池服务: 本 ...
随机推荐
- 基于CORBA/WEB技术构建三层体系结构的应用
1 问题提出 在应用系统开发过程中,CLIENT/SERVER体系结构得到了广泛的应用 .其特点是,应用程序逻辑通常分布在客户和服务器两端,客户端发出数据资源访问请求,服务器端将结果返回客户端.但CL ...
- [51CTO]反客为主 ,Linux 成为微软 Azure 上最流行的操作系统
反客为主 ,Linux 成为微软 Azure 上最流行的操作系统 [世界上唯一确定不变的就是世界在不停的变化] 三年前,微软云计算 Azure 平台 CTO Mark Russinovich 说有四分 ...
- 每个Android开发者必须知道的内存管理知识
原文:每个Android开发者必须知道的内存管理知识 拷贝在此处,以备后续查看. 相信一步步走过来的Android从业者,每个人都会遇到OOM的情况.如何避免和防范OOM的出现,对于每一个程序员来说确 ...
- npm 镜像修改
1, 修改 下载仓库为淘宝镜像 npm config set registry http://registry.npm.taobao.org/ 2, 如果要发布自己的镜像需要修改回来 npm co ...
- 【bzoj4712】洪水 树链剖分+线段树维护树形动态dp
题目描述 给出一棵树,点有点权.多次增加某个点的点权,并在某一棵子树中询问:选出若干个节点,使得每个叶子节点到根节点的路径上至少有一个节点被选择,求选出的点的点权和的最小值. 输入 输入文件第一行包含 ...
- BZOJ5212 ZJOI2018历史(LCT)
首先相当于最大化access的轻重边交换次数. 考虑每个点作为战场(而不是每个点所代表的国家与其他国家交战)对答案的贡献,显然每次产生贡献都是该点的子树内(包括自身)此次access的点与上次acce ...
- BZOJ5100 POI2018Plan metra(构造)
容易发现要么1和n直接相连,要么两点距离即为所有dx,1+dx,n的最小值.若为前者,需要满足所有|d1-dn|都相等,挂两棵菊花即可.若为后者,将所有满足dx,1+dx,n=d1,n的挂成一条链,其 ...
- http请求头、响应头文件详解
HTTP Request Header 请求头 解释 示例 Accept 指定客户端能够接收的内容类型 Accept: text/plain, text/html Accept-Charset 浏 ...
- Alpha 冲刺 —— 十分之六
队名 火箭少男100 组长博客 林燊大哥 作业博客 Alpha 冲鸭鸭鸭鸭鸭鸭! 成员冲刺阶段情况 林燊(组长) 过去两天完成了哪些任务 协调各成员之间的工作 测试服务器并行能力 学习MSI.CUDA ...
- Miiler-Robin素数测试与Pollard-Rho大数分解法
板题 Miiler-Robin素数测试 目前已知分解质因数以及检测质数确定性方法就只能\(sqrt{n}\)试除 但是我们可以基于大量测试的随机算法而有大把握说明一个数是质数 Miler-Robin素 ...