线程池核心参数配置及动态调节
2023-12-27 17:44:36
线程池的基本认识以及使用示例:https://blog.csdn.net/weixin_39439156/article/details/135099731
在实际生产中我们用线程池的难点很多时候实在配置核心参数时,因为很多时候我们也无法预计生产环境的一个使用情况,可能和我们预估情况有所差别,这时候可能我们就会去动态的去调整我们的核心参数。下面还是先简单介绍一下核心参数,再提供一个动态修改参数的demo。
1. 线程池的核心参数配置
1.1 核心参数
线程池的核心参数包括: 核心线程数(corePoolSize)、最大线程数(maximumPoolSize)、任务队列(workQueue)、线程存活时间(keepAliveTime):
1.2 工作原理
当有任务提交给线程池时,线程池会按照以下规则执行任务:
- 如果核心线程数尚未达到上限,线程池会创建一个新的核心线程来执行任务。
- 如果核心线程数已满,但是线程池中的线程总数(包括核心线程和非核心线程)未达到最大线程数,线程池会创建一个新的非核心线程来执行任务。
- 如果线程池中的线程总数已达到最大线程数,并且任务队列未满,线程池会将任务放入任务队列中等待执行。
- 如果线程池中的线程总数已达到最大线程数,并且任务队列已满,线程池会根据拒绝策略(RejectedExecutionHandler)来处理无法执行的任务。
当线程池中的线程空闲一段时间后,根据线程存活时间的设置,非核心线程可能会被销毁,以减少资源消耗。
1.3 线程池的配置思路
合理配置线程池参数对于获得最佳性能和资源利用至关重要。以下是一些常用的线程池配置建议:
- 核心线程数应根据系统的负载和并发需求进行调整。如果系统需要处理较大的并发任务,可以增加核心线程数以提高响应性能。
- 最大线程数应根据系统资源和并发负载进行调整。过多的线程数可能会浪费资源,而过少的线程数可能会导致任务排队等待执行。
- 任务队列的选择应根据具体需求来决定。如果系统需要支持大量的并发任务,可以选择无界队列来避免任务被拒绝执行。如果系统资源有限,可以选择有界队列来控制任务的数量。
- 线程存活时间应根据任务执行时间和系统负载进行调整。如果任务执行时间较长,可以增加线程存活时间以避免频繁地创建和销毁线程。
1.3 通过apollo动态配置线程池核心参数
在无法预估线上环境的情况、或者线上环境变化巨大的情况下,我们可以通过ThreadPoolExecutor 提供的set方法
对其核心参数进行动态调整。
- 初始化线程池
/**
* coreSize、maxPoolSize、aliveSeconds 均通过apollo配置
* @return
*/
@Bean("mePoolExecutor")
public ThreadPoolExecutor poolExecutor(){
ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(coreSize,
maxPoolSize,
aliveSeconds,
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(100));
return poolExecutor;
}
- 监听线程池的相关核心参数是否变化,变化则重新set
实现ConfigChangeListener
,ApplicationListener
监听ApolloConfigChangeEvent
事件,判断是否核心配置参数发生变化,如果是则重新set更新。
public class ListenerApollo implements ConfigChangeListener, ApplicationListener<ApolloConfigChangeEvent> {
@Override
public void onChange(ConfigChangeEvent configChangeEvent) {
//核心线程配置发生变化、重新set
ConfigChange coreSize = configChangeEvent.getChange("corSize");
if( coreSize!= null){
ThreadPoolExecutor executor = SpringUtil.getBean(ThreadPoolExecutor.class);
executor.setCorePoolSize(Integer.valueOf(coreSize.getNewValue()));
}
//最大线程、线程存活时间 配置发生变化、重新set todo 同上
}
@Override
public void onApplicationEvent(ApolloConfigChangeEvent event) {
this.onChange(event.getConfigChangeEvent());
}
}
- 注册listener
最后将Listener注册到我们的应用中,我这边利用springboot
的SPI
的机制,将其注册
在resource下面新建META-INFO\spring.factories文件,文件内容:
org.springframework.context.ApplicationListener=
com.zgph.employment.core.ListenerApollo
到这里就可以动态的去调成线程池相关的核心参数了
文章来源:https://blog.csdn.net/weixin_39439156/article/details/135221861
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!