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注解,帮助我们更方便的将业务逻辑提交到线程池中异步执行,今天我们就来实战体验这个线程池服务: 本 ...
随机推荐
- 关于JEE web项目 Servlet中 “/” 的解释 ;
1.关于"/" 可以代表web应用的根目录,也可以代表站点的根目录: 1>如果交给浏览器解析,则代表web站点的根目录,如果交给web服务器解析则代表项目的根目录: 2> ...
- MiniUI合并单元格
function onload(e){ var grid = e.sender; var len = grid.data.length; var data= grid.data; ,num=; var ...
- foo()与@foo()的区别
1.@foo() 是错误控制输出,foo()是正常调用输出. 2.@符号在PHP 中可以忽略错误报告,对于表达式有提示错误的,但有不影响语句执行的,可以在表达式之前加@. 3.可以把@符号放在变量.函 ...
- Linux内核0.11 bootsect文件说明
一.总体功能介绍 这是关于Linux-kernel-0.11中boot文件夹下bootsect.s源文件的说明,其中涉及到了一些基础知识可以参考这两篇文章. 操作系统启动过程 软盘相关知识和通过BIO ...
- [日常工作] 应用服务器上面应该尽量少开各种应用 --Chrome 内存泄露 让应用服务器非常缓慢
1. 前段时间修改 服务器的密码 导致应用程序的web site 启动有问题 ,打开chrome 查看了错误详细信息 但是忘记关了.. 今天反馈机器非常缓慢 简单看了下内存 吐血... 所以以后不能在 ...
- Android事件分派机制
最近一直在学习Android里面的事件分派机制,感觉很奇妙,看了很多博客和分析,才在脑子里形成了一个模糊的概念,对事件分派有了一定的认识. 于是,我画了一个图来简单明了的表述Android中事件的分派 ...
- 关于 WinScp 的一点使用经验
在嵌入式平台下 是,使用SSH登陆,可以使用WinScp提供的图形界面,支持拖拽,鼠标直接打开,甚是好用. 使用WinScp 登陆的方式有,Scp和sftp两种,之前一只用scp,但后来出现了如下错误 ...
- Windows系统下Log4Net+FileBeat+ELK日志分析系统问题总结
问题如下:1.FileBeat日志报 "dial tcp 127.0.0.1:5544: connectex: No connection could be made because the ...
- mysql 开发基础系列3
日期类型 如果要用来表示年月日,通常用DATE 来表示. 如果要用来表示年月日时分秒,通常用DATETIME 表示. 如果只用来表示时分秒,通常用TIME 来表示. TIMESTAMP表示格式 :YY ...
- Day24-Ajax文件上传
一. <input type="file" id="fafafa" name="afafaf"/> <input type ...