目的是:
  通过实现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接口方法的更多相关文章

  1. Springboot 线程池配置

    最近的项目里要手动维护线程池,然后看到一起开发的小伙伴直接用Java了,我坚信Springboot不可能没这功能,于是查了些资料,果然有,这里给一下. 首先我们都知道@Async标签能让方法异步执行, ...

  2. SpringBoot异步及线程池配置

    异步方法注解@Async 在SpringBoot中进行异步处理,可以使用异步注解@Async和@EnableAsync. @Async注解表示异步,如:@Async("asyncServic ...

  3. Spring线程池配置模板设计(基于Springboot)

    目录 线程池配置模板 基础的注解解释 常用配置参数 配置类设计 线程池使用 ThreadPoolTaskExecutor源码 线程池配置模板 springboot给我们提供了一个线程池的实现,它的底层 ...

  4. SpringBoot线程池的创建、@Async配置步骤及注意事项

    最近在做订单模块,用户购买服务类产品之后,需要进行预约,预约成功之后分别给商家和用户发送提醒短信.考虑发短信耗时的情况所以我想用异步的方法去执行,于是就在网上看见了Spring的@Async了. 但是 ...

  5. 玩转SpringBoot之定时任务@Scheduled线程池配置

    序言 对于定时任务,在SpringBoot中只需要使用@Scheduled 这个注解就能够满足需求,它的出现也给我们带了很大的方便,我们只要加上该注解,并且根据需求设置好就可以使用定时任务了. 但是, ...

  6. springboot 线程池

    我们常用ThreadPoolExecutor提供的线程池服务,springboot框架提供了@Async注解,帮助我们更方便的将业务逻辑提交到线程池中异步执行,今天我们就来实战体验这个线程池服务: 本 ...

  7. springboot线程池的使用和扩展(转)

    springboot线程池的使用和扩展 我们常用ThreadPoolExecutor提供的线程池服务,springboot框架提供了@Async注解,帮助我们更方便的将业务逻辑提交到线程池中异步执行, ...

  8. springboot线程池的使用和扩展

    我们常用ThreadPoolExecutor提供的线程池服务,springboot框架提供了@Async注解,帮助我们更方便的将业务逻辑提交到线程池中异步执行,今天我们就来实战体验这个线程池服务: 本 ...

  9. springboot线程池@Async的使用和扩展

    我们常用ThreadPoolExecutor提供的线程池服务,springboot框架提供了@Async注解,帮助我们更方便的将业务逻辑提交到线程池中异步执行,今天我们就来实战体验这个线程池服务: 本 ...

随机推荐

  1. HTTP&HTTPS、GET&POST

    1.HTTP&HTTPS: HTTP协议传输的数据都是未加密的,也就是明文的,因此使用HTTP协议传输隐私信息非常不安全,为了保证这些隐私数据能加密传输,于是网景公司设计了SSL(Secure ...

  2. [转帖] 学习一下 apache bench 的总结简介 ( LAMP的没用过..)

    PS:网站性能压力测试是性能调优过程中必不可少的一环.只有让服务器处在高压情况下才能真正体现出各种设置所暴露的问题.Apache中有个自带的,名为ab的程序,可以对Apache或其它类型的服务器进行网 ...

  3. APP接口

    <?phpClass Response{ /*** 返回json数据* @param $code 状态码* @param $message 描述信息* @param $data 数据* @par ...

  4. .net MVC4 来一个简单的分页代码

    action VodeEntities db = new NewVode.Models.VodeEntities(); ; ) { var sql = "select * ,row_numb ...

  5. JVM学习笔记(一):Java内存区域

    由于Java程序是交由JVM执行的,所以我们在谈Java内存区域划分的时候事实上是指JVM内存区域划分.在讨论JVM内存区域划分之前,先来看一下Java程序具体执行的过程: 首先Java源代码文件(. ...

  6. 【刷题】BZOJ 2693 jzptab

    Description Input 一个正整数T表示数据组数 接下来T行 每行两个正整数 表示N.M Output T行 每行一个整数 表示第i组数据的结果 Sample Input 1 4 5 Sa ...

  7. [USACO12NOV]同时平衡线Concurrently Balanced Strings DP map 思维

    题面 [USACO12NOV]同时平衡线Concurrently Balanced Strings 题解 考虑DP. \(f[i]\)表示以\(i\)为左端点的合法区间个数.令\(pos[i]\)表示 ...

  8. 【转】64位Ubuntu 16.04搭建嵌入式交叉编译环境arm-linux-gcc过程图解

    64位Ubuntu 16.04搭建嵌入式交叉编译环境arm-linux-gcc过程图解,开发裸机环境之前需要先搭建其开发环境,毕竟工欲善其事必先利其器嘛.  安装步骤 1.准备工具安装目录 下载 ar ...

  9. MVP, MVVM In Android

    MVP, MVVM In Android(新手必看)安卓MVP的理解,看完你就会用mvp了 - zq019的博客 - 博客频道 - CSDN.NEThttp://blog.csdn.net/zq019 ...

  10. loj2542「PKUWC2018」随机游走

    题目描述 给定一棵 nn 个结点的树,你从点 xx 出发,每次等概率随机选择一条与所在点相邻的边走过去. 有 QQ 次询问,每次询问给定一个集合 SS,求如果从 xx 出发一直随机游走,直到点集 SS ...