ThreadPoolExecutor的corePoolSize和maximumPoolSize

本文深入解析ThreadPoolExecutor的工作机制,包括如何根据corePoolSize和maximumPoolSize自动调整线程池大小,以及使用LinkedBlockingQueue作为任务队列时的具体行为。通过实例演示了线程池在不同情况下如何处理任务提交,直至达到其容量极限。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ThreadPoolExecutor 将根据 corePoolSize(参见 getCorePoolSize())和 maximumPoolSize(参见 getMaximumPoolSize())设置的边界自动调整池大小。当新任务在方法 execute(java.lang.Runnable) 中提交时,如果运行的线程少于 corePoolSize,则创建新线程来处理请求,即使其他辅助线程是空闲的。如果运行的线程多于 corePoolSize 而少于 maximumPoolSize,则仅当队列满时才创建新线程。

使用LinkedBlockingQueue作为示例队列:


private static void LinkedBlockingQueue(){
        ThreadFactory namedThreadFactory = new ThreadFactoryBuilder()
                .setNameFormat("demo-pool-%d").build();
        int queueCapacity = 3, corePoolSize=2, maximumPoolSize=3;
        LinkedBlockingQueue linkedBlockingQueue = new LinkedBlockingQueue(queueCapacity);
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(corePoolSize,maximumPoolSize,10, TimeUnit.SECONDS,linkedBlockingQueue,namedThreadFactory);
        for(int i=1;i<21;i++){
            Thread thread = namedThreadFactory.newThread(new Task(i));
            System.out.println("即将添加数据:"+i);
            threadPoolExecutor.execute(thread);
            System.out.println("i:"+i+", queueSize:"+linkedBlockingQueue.size()
                    +", poolSize:"+threadPoolExecutor.getPoolSize()
                    +", coreSize:"+threadPoolExecutor.getCorePoolSize()
                    +", maxSize:"+threadPoolExecutor.getMaximumPoolSize());
        }

看打印的日志:

即将添加数据:1
i:1, queueSize:0, poolSize:1, coreSize:2, maxSize:3
即将添加数据:2
i:2, queueSize:0, poolSize:2, coreSize:2, maxSize:3
即将添加数据:3
i:3, queueSize:1, poolSize:2, coreSize:2, maxSize:3
即将添加数据:4
i:4, queueSize:2, poolSize:2, coreSize:2, maxSize:3
即将添加数据:5
i:5, queueSize:3, poolSize:2, coreSize:2, maxSize:3
即将添加数据:6
i:6, queueSize:3, poolSize:3, coreSize:2, maxSize:3
即将添加数据:7
Exception in thread "main" java.util.concurrent.RejectedExecutionException

当添加第一个任务的时候,由于线程池空着,直接创建核心线程来处理请求;

当已经添加完两个请求,添加第三个请求的时候,核心线程数已满,则往队列里面添加,此时queueSize=1;

添加3、4、5任务,都被添加到了队列里面,此时queueSize=3;

添加6任务的时候,核心线程已满,队列已满,运行的线程数小于maximumPoolSize,那么线程池再处理一个任务,此时poolSize=3,线程池的任务满了;

添加7任务的时候,由于线程池里面的任务还没有执行完,而队列也是满的,线程池处理不了这么多任务了,抛出异常java.util.concurrent.RejectedExecutionException。

### ThreadPoolExecutor 中 `corePoolSize` `maximumPoolSize` 的区别及作用 #### 参数定义 `corePoolSize` 是指线程池的核心线程数,这些线程一旦被创建就会持续存在,即使它们当前没有任何任务要处理[^1]。而 `maximumPoolSize` 则表示线程池中允许存在的最大线程数量,这个数值决定了在线程池忙碌时能够额外创建多少非核心线程来处理更多的任务[^2]。 #### 工作机制 当向线程池提交任务时,如果当前运行的线程数少于 `corePoolSize`,则会优先创建新的线程去执行该任务;如果已有线程的数量达到了 `corePoolSize`,那么后续的任务将会被放入工作队列等待执行。只有当工作队列已满且正在运行的线程数小于 `maximumPoolSize` 时,才会继续创建新的非核心线程来执行任务[^3]。 #### 非核心线程管理 对于超出 `corePoolSize` 而创建的非核心线程,如果有空闲时间超过设定的 `keepAliveTime` 值,则会被终止并移除,以此实现资源的有效利用。然而,核心线程不会受到此限制的影响,除非显式调用了某些方法(如 shutdown() 或者 allowCoreThreadTimeOut(true)),否则它们始终保留在线程池中。 #### 实际应用案例分析 以固定大小线程池为例 (`Executors.newFixedThreadPool(nThreads)`),其内部实际上就是基于 `ThreadPoolExecutor` 构建而成,其中设置了相同的 `corePoolSize` `maximumPoolSize` 数值,并采用了无界的 LinkedBlockingQueue 来存储待处理任务。尽管这种配置简单易用,但由于缺乏对任务排队长度或者并发线程上限的有效控制,《阿里巴巴 Java 开发手册》建议避免直接使用此类预定义工厂方法构建线程池,转而采用更灵活可控的方式自定义实例化 `ThreadPoolExecutor` 对象[^4]。 ```java // 自定义线程池示例代码 import java.util.concurrent.*; public class CustomThreadPool { public static void main(String[] args) { int corePoolSize = 5; int maxPoolSize = 10; long keepAliveTime = 60L; BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(10); ThreadFactory threadFactory = Executors.defaultThreadFactory(); RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy(); ThreadPoolExecutor executor = new ThreadPoolExecutor( corePoolSize, maxPoolSize, keepAliveTime, TimeUnit.SECONDS, workQueue, threadFactory, handler); System.out.println("Custom ThreadPool created with Core Pool Size: " + corePoolSize + ", Maximum Pool Size: " + maxPoolSize); } } ``` 上述代码展示了如何手动定制一个具有特定行为模式的线程池,包括但不限于指定核心/最大线程数目、保持活动期限以及拒绝策略等方面的内容。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值