corePoolSize vs. maxPoolSize


点击上方 "IT牧场"
,选择 "设为星标"

技术干货每日送达!

corePoolSize vs. maxPoolSize

1. 概览

Spring中的 ThreadPoolTaskExecutor
是一个 JavaBean ,提供围绕 java.util.concurrent.ThreadPoolExecutor
的抽象实例,并作为Spring 中 org.springframework.core.task.TaskExecutor
暴露出来. 此外,它可以通过 corePoolSize、maxPoolSize、queueCapacity、allowCoreThreadTimeOut
keepAliveSeconds
的属性进行高度配置。在本教程中,我们将查看 corePoolSize
maxPoolSize
属性。

2. corePoolSize
vs. maxPoolSize

刚接触到这种抽象的用户可能很容易混淆这两个配置属性的区别。因此,让我们分别看一下。

2.1. corePoolSize

corePoolSize 是在不超时情况下,保持活跃的最少线程数。它是 ThreadPoolTaskExecutor
的一个可配置项。但是, ThreadPoolTaskExecutor* 抽象将该值的设置委托给底层的 java.util.concurrent.ThreadPoolExecutor
。为验证这一点,如果我们将 allowCoreThreadTimeOut
设置为 true
,那么所有线程都可能超时,等于将 corePoolSize
的值设置为零。

2.2. maxPoolSize

相反, maxPoolSize定义了可以创建的最大线程数
。类似地, ThreadPoolTaskExecutor
maxPoolSize
属性也将其值委托给底层的 java.util.concurrent.ThreadPoolExecutor
。为验证这点,
maxPoolSize
依赖于queueCapacity,因为

ThreadPoolTaskExecutor 只会在其队列中的项目数超过
queueCapacity*时创建一个新线程。

3. 所以,区别在哪?

corePoolSize
maxPoolSize
之间的差别似乎很明显。然而,他们的行为有些微妙之处。

当我们向
ThreadPoolTaskExecutor提交新任务时, 如果正在运行的线程少于
corePoolSize

线程,即使池中有空闲线程,或者如果正在运行的线程少于 maxPoolSize
且由 queueCapacity
定义的队列已满,它也会创建一个新线程。

接下来,让我们看一些代码,以了解每个属性何时启动的示例。

4. 举例说明

首先,假设我们有一个执行新线程的方法,它来自名为 startThreads
ThreadPoolTaskExecutor

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
的任务数是多少,我们都希望启动五个线程:

@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。因此,我们希望只启动五个线程。为了更加清晰表明只有五个线程启动,因此 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个线程。因此,我们现在希望总共启动十个线程:

@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());

}

}

同样,如果我们将 queueCapactity
设置为零并且只启动了10个任务,那么我们的 ThreadPoolTaskExecutor
中也会有10个线程。

5. 写在最后

ThreadPoolTaskExecutor
是围绕 java.util.concurrent.ThreadPoolExecutor
的强大抽象,提供了配置 corePoolSize
maxPoolSize
queueCapacity
的选项。在本教程中,我们查看了 corePoolSize
maxPoolSize
属性,以及 maxPoolSize
如何与 queueCapacity
协同工作,从而使我们能够轻松地为任何用例创建线程池

代码可在 Github 中找到!

干货分享

最近将个人学习笔记整理成册,使用PDF分享。关注我,回复如下代码,即可获得百度盘地址,无套路领取!



001:《Java并发高并发解决方案》学习笔记;



002:《深入JVM内核——原理、诊断与优化》学习笔记;



003:《Java面试宝典》



004:《Docker开源书》



005:《Kubernetes开源书》



006:《DDD速成(领域驱动设计速成)》



007: 全部



008: 加技术讨论群

近期热文

想知道更多?长按/扫码关注我吧↓↓↓
corePoolSize vs. maxPoolSize
>>>技术讨论群<<<

喜欢就点个 "在看"
呗^_^

原文 

http://mp.weixin.qq.com/s?__biz=MzI4ODQ3NjE2OA==&mid=2247486461&idx=2&sn=638986793ba3e7efabe3695690aa90ce

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。

PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » corePoolSize vs. maxPoolSize

赞 (0)
分享到:更多 ()

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址