如何设置线程池参数?美团给出了一个让面试官虎躯一震的回答。(3)

简介: 如何设置线程池参数?美团给出了一个让面试官虎躯一震的回答。(3)

动态设置的注意点有哪些?


调整的时候可能会出现核心线程数调整之后无效的情况,比如下面这种:


改变之前的核心线程数是 2,最大线程数为 5,我们动态修改核心线程数为 10。

但是从日志还是可以看出,修改之后核心线程数确实变成了 10,但活跃线程数还是为 5。


而且我调用了 prestartCoreThread 方法,该方法见名知意,你也知道是启动所有的核心线程数,所有不存在线程没有创建的问题。


这是为什么呢?


源码之下无秘密,我带你去看一眼:


java.util.concurrent.ThreadPoolExecutor#getTask


在这个方法中我们可以看到,如果工作线程数大于最大线程数,则对工作线程数量进行减一操作,然后返回 null。


所以,这个地方的实际流程应该是: 创建新的工作线程 worker,然后工作线程数进行加一操作。 运行创建的工作线程 worker,开始获取任务 task。 工作线程数量大于最大线程数,对工作线程数进行减一操作。 返回 null,即没有获取到 task。 清理该任务,流程结束。


这样一加一减,所以真正在执行任务的工作线程数的数量一直没有发生变化,也就是最大线程数。


怎么解决这个问题呢?


答案已经呼之欲出啦。


设置核心线程数的时候,同时设置最大线程数即可。其实可以把二者设置为相同的值:


这样,活动线程数就能正常提高了。


有的小伙伴就会问了:如果调整之后把活动线程数设置的值太大了,岂不是业务低峰期我们还需要人工把值调的小一点?


不存在的,还记得前面介绍 corePoolSize 参数的含义时的注解吗:


当 allowCoreThreadTimeOut 参数设置为 true 的时候,核心线程在空闲了

keepAliveTime 的时间后也会被回收的,相当于线程池自动给你动态修改了。


如何动态指定队列长度?


前面介绍了最大线程数和核心线程数的动态设置,但是你发现了吗,并没有设置队列长度的 set 方法啊?


有的小机灵鬼说先获取 Queue 对象出来再看一下呢?


还是没有,这可咋整呢?


首先我们看一下为什么没有提供队列长度的 set 方法呢:


因为队列的 capacity 是被 final 修饰了呀。


但是美团的那篇文章明明说了,他们也支持队列的动态调整呀:


可是没有详细说明,但是别着急,接着看后面的内容可以发现他们有一个名字为 ResizableCapacityLinkedBlockIngQueue 的队列:


很明显,这是一个自定义队列了。


我们也可以按照这个思路自定义一个队列,让其可以对 Capacity 参数进行修改即可。

操作起来也非常方便,把 LinkedBlockingQueue 粘贴一份出来,修改个名字,然后把 Capacity 参数的 final 修饰符去掉,并提供其对应的 get/set 方法。


然后在程序里面把原来的队列换掉:


运行起来看看效果:


可以看到,队列大小确实从 10 变成了 100,队列使用度从 100% 降到了 9%。

我后来去看了美团的那篇文章下面的评论,有个评论是这样的:


果然不出我所料。


这个过程中涉及到的面试题有哪些?


问题一:线程池被创建后里面有线程吗?如果没有的话,你知道有什么方法对线程池进行预热吗?


线程池被创建后如果没有任务过来,里面是不会有线程的。如果需要预热的话可以调用下面的两个方法:

全部启动:


仅启动一个:


问题二:核心线程数会被回收吗?需要什么设置?


核心线程数默认是不会被回收的,如果需要回收核心线程数,需要调用下面的方法:


allowCoreThreadTimeOut 该值默认为 false。


最后说一句(求关注)


点个赞吧,周更很累的,不要白嫖我,需要一点正反馈。


才疏学浅,难免会有纰漏,如果你发现了错误的地方,由于本号没有留言功能,还请你加我微信给我指出来,我对其加以修改。(我每篇技术文章都有这句话,我是认真的说的。)


感谢您的阅读,我坚持原创,十分欢迎并感谢您的关注。


我是why技术,一个不是大佬,但是喜欢分享,又暖又有料的四川好男人。


欢迎关注公众号【why技术】,坚持输出原创。分享技术、品味生活,愿你我共同进步。

目录
相关文章
|
3月前
|
缓存 Java
线程池的核心参数
线程池七大参数解析:核心线程数决定常驻线程,最大线程数控制并发上限,存活时间管理非核心线程生命周期,工作队列缓存待处理任务,线程工厂定制线程属性,拒绝策略应对任务过载,提升系统稳定性与资源利用率。
302 1
|
6月前
|
缓存 NoSQL 关系型数据库
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?
|
Java 存储
线程池的核心参数有哪些?
线程池七大核心参数:核心/最大线程数、线程保持时间及单位、阻塞队列、线程工厂与拒绝策略。
635 79
|
6月前
|
Kubernetes Linux Go
使用 Uber automaxprocs 正确设置 Go 程序线程数
`automaxprocs` 包就是专门用来解决此问题的,并且用法非常简单,只需要使用匿名导入的方式 `import _ "go.uber.org/automaxprocs"` 一行代码即可搞定。
287 78
|
6月前
|
SQL 存储 关系型数据库
美团面试:事务提交了,数据丢失 了 ?大概的原因是什么?
美团面试:事务提交了,数据丢失 了 ?大概的原因是什么?
美团面试:事务提交了,数据丢失 了 ?大概的原因是什么?
|
6月前
|
消息中间件 架构师 Java
美团面试:对比分析 RocketMQ、Kafka、RabbitMQ 三大MQ常见问题?
美团面试:对比分析 RocketMQ、Kafka、RabbitMQ 三大MQ常见问题?
美团面试:对比分析 RocketMQ、Kafka、RabbitMQ 三大MQ常见问题?
|
10月前
|
监控 Kubernetes Java
阿里面试:5000qps访问一个500ms的接口,如何设计线程池的核心线程数、最大线程数? 需要多少台机器?
本文由40岁老架构师尼恩撰写,针对一线互联网企业的高频面试题“如何确定系统的最佳线程数”进行系统化梳理。文章详细介绍了线程池设计的三个核心步骤:理论预估、压测验证和监控调整,并结合实际案例(5000qps、500ms响应时间、4核8G机器)给出具体参数设置建议。此外,还提供了《尼恩Java面试宝典PDF》等资源,帮助读者提升技术能力,顺利通过大厂面试。关注【技术自由圈】公众号,回复“领电子书”获取更多学习资料。
|
10月前
|
存储 关系型数据库 MySQL
美团面试:MySQL为什么 不用 Docker部署?
45岁老架构师尼恩在读者交流群中分享了关于“MySQL为什么不推荐使用Docker部署”的深入分析。通过系统化的梳理,尼恩帮助读者理解为何大型MySQL数据库通常不使用Docker部署,主要涉及性能、管理复杂度和稳定性等方面的考量。文章详细解释了有状态容器的特点、Docker的资源隔离问题以及磁盘IO性能损耗,并提供了小型MySQL使用Docker的最佳实践。此外,尼恩还介绍了Share Nothing架构的优势及其应用场景,强调了配置管理和数据持久化的挑战。最后,尼恩建议读者参考《尼恩Java面试宝典PDF》以提升技术能力,更好地应对面试中的难题。
|
7月前
|
人工智能 算法 数据库
美团面试:LLM大模型存在哪些问题?RAG 优化有哪些方法?_
美团面试:LLM大模型存在哪些问题?RAG 优化有哪些方法?_
|
9月前
|
数据采集 Java Linux
面试大神教你:如何巧妙回答线程优先级这个经典考题?
大家好,我是小米。本文通过故事讲解Java面试中常见的线程优先级问题。小明和小华的故事帮助理解线程优先级:高优先级线程更可能被调度执行,但并非越高越好。实际开发需权衡业务需求,合理设置优先级。掌握线程优先级不仅能写出高效代码,还能在面试中脱颖而出。最后,小张因深入分析成功拿下Offer。希望这篇文章能助你在面试中游刃有余!
155 4
面试大神教你:如何巧妙回答线程优先级这个经典考题?

热门文章

最新文章