【ThreadPoolTaskExecutor】 SpringBoot 的线程池的使用
一、配置 ThreadPoolTaskExecutor
创建一个文件夹 config ,新建一个类 ThreadPoolConfig.java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;import java.util.concurrent.ThreadPoolExecutor;/*** 线程池配置**/
@Configuration
public class ThreadPoolConfig {/*** 核心线程池大小**/private int corePoolSize = 50;/*** 最大可创建的线程数**/private int maxPoolSize = 200;/*** 队列最大长度**/private int queueCapacity = 10000;/*** 线程池维护线程所允许的空闲时间**/private int keepAliveSeconds = 300;@Bean(name = "threadPoolTaskExecutor")public ThreadPoolTaskExecutor threadPoolTaskExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setMaxPoolSize(maxPoolSize);executor.setCorePoolSize(corePoolSize);executor.setQueueCapacity(queueCapacity);executor.setKeepAliveSeconds(keepAliveSeconds);// 设置处理策略executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());return executor;}}
二、使用 ThreadPoolTaskExecutor
在其他 SpringBoot 管理的 bean 下注入上面配置的类
@Autowiredprivate ThreadPoolTaskExecutor threadPoolTaskExecutor;
使用无返回值的线程
threadPoolTaskExecutor.execute(()->{// 要执行的任务});
使用有返回值的线程
Future<?> submit = threadPoolTaskExecutor.submit(() -> {// 要执行的任务//返回 ? 对象return null;});
值得注意的是,submit
方法执行的所在的主线程会等取完返回的数据之后才会结束(只有使用了 get()
方法才会堵塞线程)
例如:
List<Future<?>> results = new ArrayList<>();//这里只是举例开启10个线程for(int i = 0;i < 10;i++){Future<?> submits = threadPoolTaskExecutor.submit(() -> {// 要执行的任务//返回 ? 对象return null;});myresults.add(submits);}//上面的线程都执行完毕,才会执行下面取数据的代码for(Future<?> result :results){//取数据(这里举例用String对象接收)String string = (String)result.get();}
三、关于处理策略
在使用线程池并且使用有界队列的时候,如果队列满了,任务添加到线程池的时候就会有问题,针对这些问题java线程池提供了以下几种策略:
- AbortPolicy
该策略是线程池的默认策略。使用该策略时,如果线程池队列满了丢掉这个任务并且抛出RejectedExecutionException异常。
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {//不做任何处理,直接抛出异常throw new RejectedExecutionException("Task " + r.toString() +" rejected from " +e.toString());}
- DiscardPolicy
这个策略是AbortPolicy的slient版本,如果线程池队列满了,会直接丢掉这个任务并且不会有任何异常。
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {//就是一个空的方法}
- DiscardOldestPolicy
这个策略从字面上也很好理解,丢弃最老的。也就是说如果队列满了,会将最早进入队列的任务删掉腾出空间,再尝试加入队列。
因为队列是队尾进,队头出,所以队头元素是最老的,因此每次都是移除对头元素后再尝试入队。
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {if (!e.isShutdown()) {//移除队头元素e.getQueue().poll();//再尝试入队e.execute(r);}}
- CallerRunsPolicy
使用此策略,如果添加到线程池失败,那么主线程会自己去执行该任务,不会等待线程池中的线程去执行。
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {if (!e.isShutdown()) {//直接执行run方法r.run();}}
- 自定义
如果以上策略都不符合业务场景,那么可以自己定义一个拒绝策略,只要实现RejectedExecutionHandler接口,并且实现rejectedExecution方法就可以了。具体的逻辑就在rejectedExecution方法里去定义就OK了。
例如:我定义了我的一个拒绝策略,叫做MyRejectPolicy,里面的逻辑就是打印处理被拒绝的任务内容
public class MyRejectPolicy implements RejectedExecutionHandler{public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {//Sender是我的Runnable类,里面有message字段if (r instanceof Sender) {Sender sender = (Sender) r;//直接打印System.out.println(sender.getMessage());}}
}
处理策略这一部分原文出自:https://blog.csdn.net/jgteng/article/details/54411423
【ThreadPoolTaskExecutor】 SpringBoot 的线程池的使用相关推荐
- SpringBoot使用线程池
SpringBoot使用线程池 软件环境 名称 版本号 jdk 1.8 springboot 2.1.6 maven 3.3.9 1.Java中创建线程池 只会介绍java中线程池的核心类Thread ...
- springboot 初始化线程池_springboot项目中线程池的使用
在application.properties添加线程池配置项 spring.task.scheduling.thread-name-prefix=SysAsyncExecutor_ spring.t ...
- SpringBoot 自定义线程池
文章目录 一.自定义线程池 1. yml配置 2. 线程池配置属性类 3. 开启异步线程支持 4. 创建自定义线程池配置类 5. service逻辑层 6. controller控制层 7. 效果图 ...
- SpringBoot—自定义线程池及并发定时任务模板
关注微信公众号:CodingTechWork,一起学习进步. 介绍 在项目开发中,经常遇到定时任务,今天通过自定义多线程池总结一下SpringBoot默认实现的定时任务机制. 定时任务模板 pom ...
- SpringBoot 引入线程池+Queue缓冲队列实现高并发下单业务
点击关注公众号,利用碎片时间学习 主要是自己在项目中(中小型项目) 有支付下单业务(只是办理VIP,没有涉及到商品库存),目前用户量还没有上来,目前没有出现问题,但是想到如果用户量变大,下单并发量变大 ...
- java springboot 监控线程池的状态
@Autowiredprivate Executor personInfoTaskExecutor;/*** 监控线程池状态* @return*/@GetMapping("asyncExce ...
- Springboot线程池的使用和扩展
我们常用ThreadPoolExecutor提供的线程池服务,springboot框架提供了@Async注解,帮助我们更方便的将业务逻辑提交到线程池中异步执行,今天我们就来实战体验这个线程池服务: 实 ...
- springboot中的线程池
1.springboot线程池定时任务类org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler 参考springboot线程 ...
- java executor spring_java 线程池(ExecutorService与Spring配置threadPoolTaskExecutor)
一.java ExecutorService实现 创建ExecutorService变量 private ExecutorService executor = null 2.执行对应任务时,首先生成线 ...
最新文章
- iOS UICollectionView的实现
- JAVA大数_棋盘覆盖
- python的数字比较好_说说 Python3 中的数字处理
- SVN 提交出错:Attempted to lock an already-locked dir
- [UOJ62]怎样跑得更快
- python弹窗输入_Python中使用tkinter弹窗获取输入文本
- linux配置php项目路径,linux下如何修改php.ini路径
- 精选论文集:三维点云有哪些必读的论文?
- ProtoBuf3语法指南(Protocol Buffers)_上
- python按字节读文件-使用Python进行二进制文件读写(转)
- 辣椒app软件测试,testflight辣椒视频
- 一元线性回归(R语言)
- 开箱即用的高匿代理抓取工具
- Android 动态修改app名称(市场和手机中显示两个不同的名称)
- Windows变慢原因分析及解决方法·系统篇
- 电路模型和电路定律(Ⅲ)
- js(javascript)中页面跳转和窗口关闭等操作
- Pulsar 社区周报| 2020-12-05 ~ 2020-12-11
- SAP FIに関する専門用語①
- 查询学生各科前三名的学生成绩
热门文章
- cc2640软件用c语言开发,CC2640R2FTI-RTOS 拿到 TI CC2640R2F 开发板 第三件事就是使用 TI-RTOS 创建 一个任务 和 使用 信号量 超时来闪烁 LED灯...
- 10个在线正则表达式测试网站推荐
- pikachu~~~CSRF(get,post,token)
- DOM4j解析XMl中碰到的问题解决
- ubuntu优化卸载不常用软件
- VC雕虫小技集(四)
- 【笔记】Oracle删除项目编号多余的数据
- Java零基础学习Java编程语言基础知…
- 针对11.2 RAC丢失OCR和Votedisk所在ASM Diskgroup的恢复手段
- oracle RAC asm管理