文章图片
一、前言大家在面试过程中 , 必不可少的问题是线程池 , 小编也是在面试中被问啥傻了 , 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 , 那么还是要创建非核心线程立刻运行这个任务;
- 产品设计|经验分享:几个产品经理面试题及答案
- Java|手机也有生产力,ColorOS这些功能你都用过吗?
- java|对标骁龙888,联发科天玑8100曝光,红米K50系列确定搭载
- java|这5款“网红电器”劝你慎买,使用3个月后,谈谈我的真实感受
- offer|直播面试、视频简历,这样才能找到新工作
- Java|入门备用机?小米Redmi 10A手机入网工信部,性价比是王道!
- Java|Java架构师概括的480页的面试笔记,拿到手立马前来分享
- javascript|惠普第五代战66预售:标配新锐龙,2022年还有低色域屏版本可选
- Java|真受不了iPhone的祖传炫光了,Find X5要改进这一问题了?
- Java|三星S22 Ultra海外卖爆,iPhone 13羡慕吗?