面试典中典之线程池的七大参数

一、七大元素解释

 创建 ThreadPoolExecutor 对象时,可以通过参数控制线程池的大小、任务队列、线程空闲时间等

1.corePoolSize(核心线程数):

表示线程池中保持的常驻核心线程数,即使线程处于空闲状态,也不会被回收。核心线程会一直存活,除非设置了 allowCoreThreadTimeOut 参数为 true,允许核心线程在一定时间内空闲时被回收。

2.maximumPoolSize(最大线程数):

表示线程池中允许的最大线程数。当线程池中的线程数达到这个值时,后续的任务会被放入任务队列中等待执行,或者执行拒绝策略,具体取决于任务队列和拒绝策略的配置。

3.keepAliveTime(线程空闲时间):

表示当线程池中的线程数大于核心线程数时,多余的空闲线程在终止前等待新任务的最长时间。超过这个时间,多余的线程会被终止,直到线程数不超过核心线程数。

4.unit(时间单位):

表示线程空闲时间的单位,通常是秒、毫秒等。

5.workQueue(任务队列):

表示用于保存等待执行的任务的队列。线程池会根据核心线程数和任务队列来决定是否创建新的线程。常用的任务队列有 LinkedBlockingQueue、ArrayBlockingQueue、SynchronousQueue 等。

6.threadFactory(线程工厂):

表示创建新线程的工厂类,用于自定义线程的名称、优先级等属性。

7.handler(拒绝策略):

表示线程池无法执行新任务时的处理策略。当线程池的线程数达到最大线程数并且任务队列已满时,会触发拒绝策略。常用的拒绝策略有 ThreadPoolExecutor.AbortPolicy、ThreadPoolExecutor.DiscardPolicy、ThreadPoolExecutor.CallerRunsPolicy 等

package com.ccy.agriculture.test;
import java.util.concurrent.*;
/**
 * 文件名称(File Name):
 * 功能描述(Description):此模块的功能描述与大概流程说明
 * 数据表(Tables):表名
 *
 * @Author wujiahao
 * 日期(Create Date):2023/7/26
 * 修改记录(Revision History):
 */


public class CustomThreadPool {
    public static void main(String[] args) {
        // 1. corePoolSize(核心线程数):5
        // 表示线程池中保持的常驻核心线程数为 5,即使线程处于空闲状态,也不会被回收。
        int corePoolSize = 5;

        // 2. maximumPoolSize(最大线程数):10
        // 表示线程池中允许的最大线程数为 10。当线程池中的线程数达到这个值时,
        // 后续的任务会被放入任务队列中等待执行,或者执行拒绝策略。
        int maximumPoolSize = 10;

        // 3. keepAliveTime(线程空闲时间):60
        // 表示当线程池中的线程数大于核心线程数时,多余的空闲线程在终止前等待新任务的最长时间为 60 秒。
        // 超过这个时间,多余的线程会被终止,直到线程数不超过核心线程数。
        long keepAliveTime = 60;

        // 4. unit(时间单位):TimeUnit.SECONDS
        // 表示线程空闲时间的单位为秒。
        TimeUnit unit = TimeUnit.SECONDS;

        // 5. workQueue(任务队列):LinkedBlockingQueue
        // 表示用于保存等待执行的任务的队列为 LinkedBlockingQueue。
        // LinkedBlockingQueue 是一个无界队列,可以保存无限数量的等待执行任务。
        BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>();

        // 6. threadFactory(线程工厂):默认的线程工厂
        // 不对线程工厂进行自定义,使用默认的线程工厂。

        // 7. handler(拒绝策略):ThreadPoolExecutor.AbortPolicy
        // 当线程池的线程数达到最大线程数并且任务队列已满时,采用默认的拒绝策略 AbortPolicy,
        // 即抛出 RejectedExecutionException 异常,拒绝新的任务执行。

        // 创建自定义线程池
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
                corePoolSize,              // 核心线程数
                maximumPoolSize,           // 最大线程数
                keepAliveTime,             // 线程空闲时间
                unit,                      // 时间单位
                workQueue                  // 任务队列
        );

        // 提交任务给线程池执行
        for (int i = 1; i <= 20; i++) {
            final int taskNumber = i;
            threadPool.execute(() -> {
                System.out.println("Task " + taskNumber +
                 " is being executed by Thread " + Thread.currentThread().getName());
            });
        }

        // 关闭线程池
        threadPool.shutdown();
    }
}

这里可以打印出每个任务在哪个线程执行,不需要一个一个地等待前面的任务完成才能开始执行,可以并行执行多个任务,从而更好地利用系统资源
在这里插入图片描述

让主线程在控制台打印,可以发现主线程和线程池里的线程并发执行任务
在这里插入图片描述

二、CountDownLatch扩展

 现实中很多业务会让子线程完成所有任务后再执行主线程,比如海量Excel表导入,要先分表读取数据再导入,这时要控制主线程要在最后执行任务,于是Java引入了CountDownLatch对象。
在这里插入图片描述
 CountDownLatch定义一个初始值,主线程调用await()方法阻塞线程,然后每当子线程执行任务时调用countDown()方法,每调用一次计数值减一,当计数值为0时就可以唤醒主线程。

countDownLatch.await(2000,TimeUnit.MILLISECONDS);

 打个比方就是你去餐馆点了20个菜,餐馆有5个厨师帮你做菜,每做一道菜就在订单上划掉对应的菜(减一操作),当所有菜做好了就可以进行上菜这个主线程了(不要跟我杠什么可以边做菜边上菜,我这个餐馆就是要做完所有菜才能上菜)
 await()也可以加参数,以保证主线程必须执行。下面这串代码表示不管子线程任务是否执行完,2000毫秒之后就执行主线程。我遇过子线程拒绝新任务的情况,这样主线程就不会执行了。

友情提示:以上为纯八股文🤡

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值