网站首页 > 技术文章 正文
最近忙着整理一个“屎山”项目,2017年的项目,也不算老,上篇文章多线程OOM也是这个“屎山”项目的一角。今天我们来讲上篇文章提到的创建线程池的7个参数,说到这里,有的小伙伴就会问了,“为什么是7个参数呢?我创建线程池不需要7个参数呀。”
进入正题,且听我细细道来。
JDK为了降低我们使用线程池的门槛,封装了一些创建线程池的方法。
Executors类里面封装的创建线程池方法
如:Executors.newFixedThreadPool、Executors.newSingleThreadExecutor、Executors.newCachedThreadPool,由于把门槛降得太低,我们就掉以轻心了,不会过多的查看底层的实现,直接按照参数提示填入参数,然后可怕的事情就发生了。
一起来看看这些方法的底层实现吧~
newFixedThreadPool的实现
newSingleThreadExecutor的实现
newCachedThreadPool的实现
看了上面的底层实现以后,我们知道其实底层最后都是调用ThreadPoolExecutor来创建线程池。
打开ThreadPoolExecutor类,找到其构造方法:
ThreadPoolExecutor构造方法
数一数,参数最多的构造方法,是7个吧,这就回答文章开头那位小伙伴的疑问了。
这里我们也可以稍微总结性的说:由于JDK封装的快速方法都是通过ThreadPoolExecutor来创建线程池,所以我们只需要把ThreadPoolExecutor7个构造参数理解了,也就基本上知道怎么创建线程池了。
7个构造参数的方法
corePoolSize:核心线程数
maximumPoolSize:最高峰线程数量,包含核心线程数
keepAliveTime:最高峰线程的存活时间
unit:存活时间的单位
workQueue:等候区队列
threadFactory:线程创建工厂
handler:拒绝策略
看了参数懵的没事,大概有个印象就行。
这里拿具体银行办理业务的场景来描述这些参数,假设有此场景:
午休时间去银行办理业务,银行有4个窗口,由于是午休的时间,当前只打开了2个窗口办理业务,客户取号后,在候客区等着叫号办理业务。由于天气好,来银行办理业务的客户特别多,把银行的候客区也塞得满满当当的,这个时候银行就在门口竖立起一块牌子:“今日暂停办理业务。”
银行办理业务流程图
结合流程图来描述,银行有9个客户来办理业务,当值窗口有2个,未开窗口有2个,候客区座位有5个。
当值窗口理解为我们的核心线程数(corePoolSize),当办理业务高峰期来临的时候,打开之前的未开窗口,这个时期办理业务的窗口为当值窗口 + 未开窗口,即最高峰线程数量(maximumPoolSize);如果这个时候继续有顾客进来,会进入候客区,即等候区队列(workQueue),假如这个时候有第10个客户来办理业务,当值窗口,未开窗口,候客区都已经满了的时候,就会暂停办理业务,即拒绝策略(handler);其中我们没有说明的最高峰线程的存活时间和存活时间的单位和线程创建工厂这三个参数。线程创建工厂根据字面意思直接理解就是创建线程的对象,而最高峰线程的存活时间(keepAliveTime)和存活时间的单位(unit)就是在业务处理完毕以后,来临时支援服务的窗口等待多久进行窗口释放,回归到核心线程数的数量。
没有理解也没有关系,继续通过代码来理解。
取钱函数
// 取钱函数
public static void withdraw() {
try {
// 取钱需要20秒
System.out.println(Thread.currentThread().getName() + "正在取钱业务 ...");
Thread.sleep(20000);
System.out.println(Thread.currentThread().getName() + "取钱业务完成");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
具体执行
// 申明参数
int corePoolSize = 2;
int maximumPoolSize = 4;
long keepAliveTime = 10;
TimeUnit unit = TimeUnit.SECONDS;
BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<Runnable>(5);
ThreadFactory threadFactory = Executors.defaultThreadFactory();
RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();
// 创建
ExecutorService threadPool = new ThreadPoolExecutor(corePoolSize,
maximumPoolSize,
keepAliveTime,
unit,
workQueue,
threadFactory,
handler
);
// 执行具体的业务
try {
for (int i = 1; i <= 9; i++) {
threadPool.execute(t::withdraw);
}
} catch (Exception exception) {
exception.printStackTrace();
} finally {
threadPool.shutdown();
}
修改等待队列
多线程的7个参数理解了吗?没有理解的,对照银行业务流程图和代码多看几遍,应该就能理解了。
- 上一篇: 「高频面试」解释线程池的各个参数含义
- 下一篇: 一文搞懂线程池中的执行原则和核心配置参数
猜你喜欢
- 2024-10-22 线程池调优之动态参数配置 动态设置线程池大小
- 2024-10-22 java线程池参数及使用 java线程池的用法
- 2024-10-22 面试官:说说你对线程池的了解 线程池实现原理面试
- 2024-10-22 「每日分享」高阶程序员需要掌握的常见性能优化策略
- 2024-10-22 池化技术学习 池化方法
- 2024-10-22 「Java基础」「多线程」-线程池 java多个线程池
- 2024-10-22 线程池配置的常见误区 线程池配置参数有哪些
- 2024-10-22 创建线程池参数有哪些作用? 创建线程池的7个参数
- 2024-10-22 一文搞懂!多线程之间的通信及线程池
- 2024-10-22 码农大叔带你——解析线程池 线程池的主要处理流程
你 发表评论:
欢迎- 最近发表
-
- 吴谨言专访大反转!痛批耍大牌后竟翻红,六公主七连发力显真诚
- 港股2月28日物业股涨幅榜:CHINAOVSPPT涨1.72%位居首位
- 港股2月28日物业股午盘:CHINAOVSPPT涨1.72%位居首位
- 港股3月2日物业股涨幅榜:CHINAOVSPPT涨1.03%位居首位
- 港股3月2日物业股午盘:CHINAOVSPPT涨1.03%
- 天赋与心痛的背后:邓鸣贺成长悲剧引发的深刻反思
- 冯小刚女儿徐朵追星范丞丞 同框合照曝光惹人羡,回应网友尽显亲民
- “资本大佬”王冉:51岁娶小17岁童瑶,并承诺余生为娇妻保驾护航
- 港股3月2日物业股午盘:CHINAOVSPPT涨1.03%位居首位
- 「IT之家开箱」vivo S15 图赏:双镜云窗,盛夏风光
- 标签列表
-
- oraclesql优化 (66)
- 类的加载机制 (75)
- feignclient (62)
- 一致性hash算法 (71)
- dockfile (66)
- 锁机制 (57)
- javaresponse (60)
- 查看hive版本 (59)
- phpworkerman (57)
- spark算子 (58)
- vue双向绑定的原理 (68)
- springbootget请求 (58)
- docker网络三种模式 (67)
- spring控制反转 (71)
- data:image/jpeg (69)
- base64 (69)
- java分页 (64)
- kibanadocker (60)
- qabstracttablemodel (62)
- java生成pdf文件 (69)
- deletelater (62)
- com.aspose.words (58)
- android.mk (62)
- qopengl (73)
- epoch_millis (61)
本文暂时没有评论,来添加一个吧(●'◡'●)