Java|Java面试必问之线程池的创建使用、线程池的核心参数、线程池的底层工作原理

Java|Java面试必问之线程池的创建使用、线程池的核心参数、线程池的底层工作原理

文章图片


一、前言大家在面试过程中 , 必不可少的问题是线程池 , 小编也是在面试中被问啥傻了 , JUC就了解的不多 。 加上做系统时 , 很少遇到 , 自己也是一知半解 。 如果还不了解线程池的小伙伴 , 一定要认真看完 , 你会有收获的哈!!最后也为大家汇总了一套2022Java面试题 , 需要的小伙伴私信【面试】哦
二、线程池创建使用
答:使用Executors看一下源码是有好多个 , 经常用的也就三个 , 今天就展示靠上的五种 。
//创建一个定长线程池 , 超出的线程会在队列中等待ExecutorService executorService = Executors.newFixedThreadPool(5);//创建一个单线程化的线程池 , 它只会用唯一的工作线程来执行任务 , ExecutorService executorService1 = Executors.newSingleThreadExecutor();//创建一个可缓存线程池 , 可以自动扩容 , 扩容大小为int最大值 , 因为太大可以直接理解为无限大ExecutorService executorService2 = Executors.newCachedThreadPool();//创建一个定长线程池 , 该线程池可以安排命令在给定延迟后运行 , 或定期执行 。 ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(5);//1.8新增-创建一个带并行级别的线程池 , 并行级别决定了同一时刻最多有多少个线程在执行 , 不传参数默认为CPU个数// Runtime.getRuntime().availableProcessors()查看本机CPU个数ExecutorService executorService3 = Executors.newWorkStealingPool();

三、线程池的核心参数//创建线程池 , 底层代码public ThreadPoolExecutor(int corePoolSize
                         int maximumPoolSize
                         long keepAliveTime
                         TimeUnit unit
                         BlockingQueue<Runnable> workQueue
                         ThreadFactory threadFactory
                         RejectedExecutionHandler handler) {    if (corePoolSize < 0 ||
       maximumPoolSize <= 0 ||
       maximumPoolSize < corePoolSize ||
       keepAliveTime < 0)        throw new IllegalArgumentException();    if (workQueue == null || threadFactory == null || handler == null)        throw new NullPointerException();    this.corePoolSize = corePoolSize;    this.maximumPoolSize = maximumPoolSize;    this.workQueue = workQueue;    this.keepAliveTime = unit.toNanos(keepAliveTime);    this.threadFactory = threadFactory;    this.handler = handler;


1. corePoolSize:线程池中的核心线程数 , 核心线程会一直存在 , 即使没有任务执行 。
2. maximumPoolSize:线程池能够容纳同时执行的最大线程数 , 此值必须大于等于1
3. keepAliveTime:当线程数大于核心数时 , 这是多余空闲线程在终止前等待新任务的最长时间 。 (意思就是本来核心线程三个 , 已占满 , 扩展到最大线程数到5 , 解决完后没有线程任务了 , 这时设置一个时间 , 过了这个时间被扩展的2个非核心线程会被回收)
4. unit:keepAliveTime的时间单位 。
5. workQueue:任务队列 , 被提交但尚未被执行的任务 , 相当于去饭店吃饭 , 餐桌满了 , 要在外边排队(阻塞队列)
6. threadFactory:表示生成线程池中工作线程的线程工厂 , 用于创建线程一般用默认的即可 。
7. handler:拒绝策略 , 表示当队列满了并且工作线程大于等于线程池的最大线程数 。
四、线程池的底层工作原理- 主要处理流程图(来源百度)

- 底层工作原理图(来源尚硅谷阳哥)

- 流程梳理
1. 在创建了线程池后 , 等待提交过来的任务请求 。  
2. 当调用execute()方法添加一个请求任务时 , 线程池会做如下判断: 
2.1 如果正在运行的线程数量小于corePoolSize , 那么马上创建线程运行这个任务; 
2.2 如果正在运行的线程数量大于或等于corePoolSize , 那么将这个任务放入队列; 
2.3 如果这时候队列满了且正在运行的线程数量还小于maximumPoolSize , 那么还是要创建非核心线程立刻运行这个任务;