网站首页 > 技术文章 正文
Spring ThreadPoolTaskExecutor线程池corePoolSize vs maxPoolSize
btikc 2024-10-22 10:30:50 技术文章 11 ℃ 0 评论概述
Spring ThreadPoolTaskExecutor是一个JavaBean,它提供了一个基于java.util.concurrent.ThreadPoolExecutor和org.springframework.core.task.TaskExecutior的线程池实例。
可以通过corePoolSize、maxPoolSize、queueCapacity、allowCoreThreadTimeOut和keepAliveSeconds等属性进行细粒度配置。
本文重点示例corePoolSize和maxPoolSize之间的区别。
corePoolSize vs maxPoolSize
- corePoolSize:不超时的情况下保持生存的最小工作线程数。如果我们将allowCoreThreadTimeOut设置为true,则相当于将corePoolSize的值设置为零。
- maxPoolSize:可以创建的最大线程数。maxPoolSize取决于queueCapacity,因为ThreadPoolTaskExecutor只有在其队列中的任务数超过queueCapacity时才会创建新线程。
当我们向ThreadPoolTaskExecutor提交一个新任务时,如果运行的线程少于corePoolSize,即使池中有空闲线程,或者运行的线程低于maxPoolSize,并且queueCapacity定义的队列已满,都会创建一个新线程。
示例
首先,假设我们有一个实现ThreadPoolTaskExecutor执行新线程的方法startThreads:
public void startThreads(ThreadPoolTaskExecutor taskExecutor, CountDownLatch countDownLatch,
int numThreads) {
for (int i = 0; i < numThreads; i++) {
taskExecutor.execute(() -> {
try {
Thread.sleep(100L * ThreadLocalRandom.current().nextLong(1, 10));
countDownLatch.countDown();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
}
}
- 让我们测试ThreadPoolTaskExecutor的默认配置,它定义了只有一个线程的corePoolSize、无界的maxPoolSize和无界的queueCapacity。因此,无论我们启动多少任务,都只有一个线程在运行:
@Test
public void whenUsingDefaults_thenSingleThread() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.afterPropertiesSet();
CountDownLatch countDownLatch = new CountDownLatch(10);
this.startThreads(taskExecutor, countDownLatch, 10);
while (countDownLatch.getCount() > 0) {
Assert.assertEquals(1, taskExecutor.getPoolSize());
}
}
- 如果将corePoolSize更改为最多5个线程,其他参数仍然按默认值,无论提交给ThreadPoolTaskExecutor的任务数量如何,都会启动5个线程:
@Test
public void whenCorePoolSizeFive_thenFiveThreads() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(5);
taskExecutor.afterPropertiesSet();
CountDownLatch countDownLatch = new CountDownLatch(10);
this.startThreads(taskExecutor, countDownLatch, 10);
while (countDownLatch.getCount() > 0) {
Assert.assertEquals(5, taskExecutor.getPoolSize());
}
}
- 类似地,可以将maxPoolSize增加到10,同时将corePoolSize保留为5。无论提交给ThreadPoolTaskExecutor的任务数量如何,也都只有5个线程启动,因为queueCapacity仍然是无限制的:
@Test
public void whenCorePoolSizeFiveAndMaxPoolSizeTen_thenFiveThreads() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(5);
taskExecutor.setMaxPoolSize(10);
taskExecutor.afterPropertiesSet();
CountDownLatch countDownLatch = new CountDownLatch(10);
this.startThreads(taskExecutor, countDownLatch, 10);
while (countDownLatch.getCount() > 0) {
Assert.assertEquals(5, taskExecutor.getPoolSize());
}
}
- 我们现在重复前面的测试,但是将queueCapacity增加到10,并启动20个线程。因此总共会启动10个线程:
@Test
public void whenCorePoolSizeFiveAndMaxPoolSizeTenAndQueueCapacityTen_thenTenThreads() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(5);
taskExecutor.setMaxPoolSize(10);
taskExecutor.setQueueCapacity(10);
taskExecutor.afterPropertiesSet();
CountDownLatch countDownLatch = new CountDownLatch(20);
this.startThreads(taskExecutor, countDownLatch, 20);
while (countDownLatch.getCount() > 0) {
Assert.assertEquals(10, taskExecutor.getPoolSize());
}
}
同样,如果我们将queueCapacity设置为0,并且只启动10个任务,那么ThreadPoolTaskExecutor中也将会有10个线程。
结论
初始化线程池ThreadPoolTaskExecutor要显式指定corePoolSize、maxPoolSize、queueCapacity这三个参数的值,不能用默认值避免任务提交累积导致内存溢出OOM。
corePoolSize可以考虑与内核数保持一致。maxPoolSize和queueCapacity需要考虑到并发吞吐量来确定其值。
猜你喜欢
- 2024-10-22 线程池调优之动态参数配置 动态设置线程池大小
- 2024-10-22 java线程池参数及使用 java线程池的用法
- 2024-10-22 面试官:说说你对线程池的了解 线程池实现原理面试
- 2024-10-22 「每日分享」高阶程序员需要掌握的常见性能优化策略
- 2024-10-22 池化技术学习 池化方法
- 2024-10-22 「Java基础」「多线程」-线程池 java多个线程池
- 2024-10-22 线程池配置的常见误区 线程池配置参数有哪些
- 2024-10-22 创建线程池参数有哪些作用? 创建线程池的7个参数
- 2024-10-22 一文搞懂!多线程之间的通信及线程池
- 2024-10-22 码农大叔带你——解析线程池 线程池的主要处理流程
你 发表评论:
欢迎- 最近发表
-
- 吴谨言专访大反转!痛批耍大牌后竟翻红,六公主七连发力显真诚
- 港股2月28日物业股涨幅榜:CHINAOVSPPT涨1.72%位居首位
- 港股2月28日物业股午盘:CHINAOVSPPT涨1.72%位居首位
- 港股3月2日物业股涨幅榜:CHINAOVSPPT涨1.03%位居首位
- 港股3月2日物业股午盘:CHINAOVSPPT涨1.03%
- 天赋与心痛的背后:邓鸣贺成长悲剧引发的深刻反思
- 冯小刚女儿徐朵追星范丞丞 同框合照曝光惹人羡,回应网友尽显亲民
- “资本大佬”王冉:51岁娶小17岁童瑶,并承诺余生为娇妻保驾护航
- 港股3月2日物业股午盘:CHINAOVSPPT涨1.03%位居首位
- 「IT之家开箱」vivo S15 图赏:双镜云窗,盛夏风光
- 标签列表
-
- oraclesql优化 (66)
- 类的加载机制 (75)
- feignclient (62)
- 一致性hash算法 (71)
- dockfile (66)
- 锁机制 (57)
- javaresponse (60)
- 查看hive版本 (59)
- phpworkerman (57)
- spark算子 (58)
- vue双向绑定的原理 (68)
- springbootget请求 (58)
- docker网络三种模式 (67)
- spring控制反转 (71)
- data:image/jpeg (69)
- base64 (69)
- java分页 (64)
- kibanadocker (60)
- qabstracttablemodel (62)
- java生成pdf文件 (69)
- deletelater (62)
- com.aspose.words (58)
- android.mk (62)
- qopengl (73)
- epoch_millis (61)
本文暂时没有评论,来添加一个吧(●'◡'●)