线程池corePoolSize和maximumPoolSize关系

为了了解corePoolSize和maximumPoolSize关系,先用测试代码进行测试:

第一个例子:

//使用只能5个有限队列,corePoolSize=2, maxPoolSize=10
        ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 10,
                0L, TimeUnit.MILLISECONDS,
                new ArrayBlockingQueue<>(5));
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());

        //创建15个线程
        for (int i = 0; i < 15; i++) {
            final int a = i;
            executor.submit(() -> {
                try {
                    Thread.sleep(500);
                    System.out.println(a + "   --- " + executor.getQueue().size());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }

        executor.shutdown();

如果创建16个线程,则有一个线程会被抛弃,

也就是:(1)可以创建最大的线程数 = 队列最大长度 + maxPoolSize,   优先使用队列,如果队列满了,才使用maxPoolSize

(2)如果使用无界队列(比如:LinkedBlockingQueue),则可以创建无穷个线程,直到内存溢出,maxPoolSize永远用不上

第二个例子:

public static void main(String[] args) {
        //使用只能5个有限队列,corePoolSize=15, maxPoolSize=15
        ThreadPoolExecutor executor = new ThreadPoolExecutor(15, 15,
                0L, TimeUnit.MILLISECONDS,
                new ArrayBlockingQueue<>(5));

        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());


        //创建15个线程
        for (int i = 0; i < 20; i++) {
            executor.execute(new MyThread(i));
        }

        executor.shutdown();
    }

    public static class MyThread implements Runnable {

        private int flag;
        private boolean inQueue;

        public MyThread(int flag) {
            this.flag = flag;
        }


        @Override
        public void run() {
            System.out.println("线程编号:" + getFlag() + "   是否被加入队列:" + inQueue);
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        public boolean isInQueue() {
            return inQueue;
        }

        public void setInQueue(boolean inQueue) {
            this.inQueue = inQueue;
        }

        public int getFlag() {
            return flag;
        }
    }

如果corePoolSize=15,创建15个线程,则直接执行15个线程,无需加入队列,

如果corePoolSize=14,直接执行14个线程,1个线程进入队列

也就是:(1)进入队列的线程数量 = max(线程数-corePoolSize, 队列最大长度)

             (2)直接执行的线程数量 = if(线程数量>corePoolSize and 线程数量<=队列最大长度) {

                                                               return 线程数量-corePoolSize

                                               } else if(线程数量>队列最大长度 and 线程数量<=maxPoolSize + 队列最大长度) {

                                                                return 线程数量 - 队列最大长度

                                                } else if(线程数量>maxPoolSize + 队列最大长度){

                                                                return 线程数量 - 队列最大长度( 其他被抛弃或报错)

                                                }

### 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、付费专栏及课程。

余额充值