千锋教育-做有情怀、有良心、有品质的IT职业教育机构

400-811-9990
当前位置:首页  >  技术文章  >  正文

Spring框架下ThreadPoolTaskExecutor线程池的使用

时间:2023-03-01 17:31     来源:千锋教育 作者:qyf

  一. 问题阐述

  最近千锋java老师一个已经参加工作的学生,要给他们公司迭代开发一个营销活动,其中有一个功能是:当运营人员录入一次活动的同时,需要给这次活动生成一定数量的礼品兑换券。

  千锋java老师的这个学生,虽然把这个功能实现了,但效果却不尽理想,于是他就跑来咨询我该怎么进行优化。千锋java老师思索了一下,就结合他这个项目的实际场景,考虑到要生成大数量礼品券的过程比较耗时,于是千锋java老师就决定把生成礼品券的逻辑使用线程进行异步执行。

  最终千锋java老师选择使用Spring下的线程池工具类ThreadPoolTaskExecutor来创建线程,经过这样一番技术优化后,千锋java老师就帮这个学生完满完成了他们公司布置的任务。那么接下来千锋java老师就给大家介绍一下刚才提到的ThreadPoolTaskExecutor的使用方法和注意事项。

  二. 快速使用

  1. 创建项目入口类

  首先我们创建一个入口类,并在该入口类上添加@EnableAsync注解。

  @SpringBootApplication

  @EnableAsync

  public class AsyncdemoApplication {

  public static void main(String[] args) {

  SpringApplication.run(AsyncdemoApplication.class, args);

  }

  }

  2. 编写业务方法

  接下来我们把需要异步执行的业务逻辑单独抽取成一个方法,在方法上也加上@Async注解。

  @Slf4j

  @Service

  public class AsyncService {

  /**

  * 异步调用无返回值

  * @throws InterruptedException

  */

  @Async

  public void asyncProcess() throws InterruptedException {

  log.info("异步任务, 当前线程的名字是 -> {}",

  Thread.currentThread().getName());

  }

  /**

  * 带有返回值的异步调用

  * @throws InterruptedException

  */

  @Async

  public FutureasyncProcessHasReturn() throws InterruptedException {

  log.info("异步任务(有返回值), 当前线程的名字是 -> {}",

  Thread.currentThread().getName());

  TimeUnit.SECONDS.sleep(2);

  return new AsyncResult<>(100);

  }

  }

  3. 编写junit单元测试

  接下来我们就编写一个单元测试类,对上面编写好的业务代码进行调用测试。

  @SpringBootTest

  @Slf4j

  public class AsyncServiceTests {

  @Autowired

  private AsyncService asyncService;

  /**

  * 测试无返回值的线程调用

  * @throws InterruptedException

  */

  @Test

  public void test01() throws InterruptedException {

  log.info("调用开始,当前线程是 {}",Thread.currentThread().getName());

  asyncService.asyncProcess();

  Thread.sleep(100);

  log.info("调用结束,当前线程是 {}",Thread.currentThread().getName());

  }

  /**

  * 测试有返回值的线程调用

  * @throws InterruptedException

  */

  @Test

  public void test02() throws InterruptedException, ExecutionException {

  log.info("调用开始,当前线程是 {}",Thread.currentThread().getName());

  FutureintegerFuture = asyncService.asyncProcessHasReturn();

  Integer integer = integerFuture.get();

  System.out.println(integer);

  log.info("调用结束,当前线程是 {}",Thread.currentThread().getName());

  }

  }

  我们可以分别执行两个测试用例。

  无返回值的测试用例的测试结果:

1673232705510.image

  有返回值的测试用例的测试结果:

1673232705510.image

  三. 程序优化

  从上面的测试结果中我们不难看出,在Spring下我们要使用线程池其实非常的简单,只需在要异步调用的方法上加上@Async注解即可。以后调用该方法时,Spring就会自动使用默认的线程池,创建一个线程异步调用该方法。

  但这样做会不会有什么问题呢?有没有我们需要优化的点呢?

  答案是肯定的!Spring默认使用的Executor bean,和我们使用JDK中的Executors创建的线程池一样,都存在着阻塞队列的长度过长,可能会堆积大量的请求,从而导致OOM的问题。所以为了规避资源耗尽,我们一般会自己配置Executor bean(具体描述参照阿里巴巴开发规范1.4版),具体优化代码如下:

  @Configuration

  @Slf4j

  public class AsyncConfig implements AsyncConfigurer {

  @Override

  @Bean("cs2105ThreadPool")

  public Executor getAsyncExecutor() {

  ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();

  // 设置核心线程数

  executor.setCorePoolSize(10);

  // 设置最大线程数

  executor.setMaxPoolSize(20);

  // 设置阻塞队列的容量

  executor.setQueueCapacity(20);

  // 除了核心线程数以外的线程的存货时间

  executor.setKeepAliveSeconds(60);

  // 设置线程池的线程的名称的前缀

  executor.setThreadNamePrefix("cs2105_");

  executor.setWaitForTasksToCompleteOnShutdown(true);

  executor.setAwaitTerminationSeconds(60);

  // 拒绝策略

  executor.setRejectedExecutionHandler(

  new ThreadPoolExecutor.AbortPolicy()

  );

  executor.initialize();

  return executor;

  }

  配置了自定义的Executor bean 之后,我们再次运行测试case,发现运行结果如下:

  

image.png

  四. 结语

  线程池在Java中一直都是一个非常重要的知识点,我们在面试中也会经常遇到这方面的题,希望大家好好掌握这里面的基础知识。

相关文章

  • 北京总部地址:北京市海淀区宝盛北里西区28号中关村智诚科创大厦4层
    北京沙河校区:北京市昌平区沙阳路18号北京科技职业技术学院广场服务楼
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、互联网营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 深圳校区地址:深圳市宝安区宝安大道5010号西部硅谷B座A区6层A605/B座C区1层108
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、互联网营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 上海校区地址:上海市宝山区同济支路199号智慧七立方3号楼2-4层
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、互联网营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 广州校区地址:广州市白云区永平街永泰学山塘学山文化创意谷A1栋六楼
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、互联网营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 郑州二七区校区地址:郑州市二七区航海中路60号海为科技园C区10层
    郑州高新区校区地址:郑州市高新区金梭路与银杏路交叉口教育科技产业园南门D座4层
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、互联网营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 大连校区地址:辽宁省大连市高新园区爱贤街10号大连设计城A座901
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、互联网营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 武汉金融港校区地址:武汉市东新区光谷大道77号金融港B18栋三楼
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、互联网营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 成都校区地址:成都市高新区肖家河沿街138号肖家河大厦三楼
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、互联网营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 西安校区地址:西安市雁塔区高新六路52号立人科技C座西区4楼
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、互联网营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 杭州旺田校区:浙江省杭州市江干区九堡旺田书画城A座4层
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、互联网营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 青岛校区地址:青岛市市北区龙城路31号卓越世纪中心4号楼5层
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、互联网营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 重庆校区地址:重庆市九龙坡区科园一路3号渝高大厦9楼
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、互联网营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 长沙校区地址:湖南省长沙市岳麓区麓谷企业广场A2栋三单元306号
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、互联网营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 哈尔滨校区地址:哈尔滨市松北区世泽路689号 科技创新城4号楼1101
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、互联网营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 南京校区地址:南京市建邺区应天大街780号弘辉产业园1栋2层
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、互联网营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 太原校区地址:太原市小店区长治路230号能源互联网大厦6层
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、互联网营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 沈阳校区地址:辽宁省沈阳市浑南区世纪路16号东大软件园B园B1座A201
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、互联网营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 合肥校区地址:合肥市包河区徽州大道396号东方广场B座12A
    咨询电话:400-811-9990
    面授课程:HTML5大前端培训、JavaEE+分布式开发培训、Python全栈+人工智能培训、全链路UI/UE设计培训、云计算培训、全栈软件测试培训、大数据+人工智能培训、智能物联网+嵌入式培训、Unity游戏开发培训、Go语言开发培训、PHP全栈+服务器集群培训、网络安全培训、互联网营销培训、好程序员
    认证课程:软考、、PMP认证、红帽RHCE认证
  • 千锋教育服务号

    关注千锋学习站小程序
    随时随地免费学习课程

  • 千锋教育移动站

    扫一扫快速进入
    千锋移动端页面

  • 千锋互联服务号

    扫码匿名提建议
    直达CEO信箱