【技术分享】线程池核心线程数与最大线程数的区别|任务数超过最大线程数怎么办

我记得有一次,我在公司里负责一个后台处理系统,那时候我们用了一个线程池来处理用户提交的任务。
那天,系统突然接到了一个高峰期的任务请求,短短几分钟内,提交的任务数就超过了我们的最大线程数,达到了5 0个。

我们设置的核心线程数是1 0,最大线程数是2 0,所以当任务数超过2 0时,线程池就开始启动备用线程来处理。
但是,很快备用线程也用完了,这时候任务数已经超过了5 0。
我查看了一下日志,发现线程池开始抛出RejectedExecutionException异常。

那时候,我就在想,如果我们没有设置足够的最大线程数,或者没有合适的饱和策略,系统可能会因为处理不过来任务而崩溃。
幸好,我们之前已经预见到这种情况,所以设置了CallerRunsPolicy策略,当任务无法被线程池处理时,就回退到调用者线程去执行。

不过,我还是有点好奇,如果我们的系统没有这样的应对措施,那会是什么样子呢?会不会有任务被永久丢弃,或者系统直接崩溃?也许,这就是为什么我们需要深入了解线程池的配置和策略吧。

玩家实践:调整 CPU 线程以获得更好的游戏性能

上周有个客人问我怎么调整CPU线程以提升游戏性能,我给他详细解释了一番。
首先,得知道这事儿的核心是得根据你的硬件配置和工作负载来优化线程数量,别让线程太多反而成了负担。

先说说传统线程数量的算法吧,它一般就是用逻辑核心数减去2 ,为关键线程留出两个核心。
但这个方法在现代硬件上可能就不太灵光了。

比如说,当物理核心超过8 个的时候,线程并行带来的好处可能被调度开销给抵消了,甚至可能导致性能下降。
我之前就看过一些高端桌面系统(物理核心数超过8 个)的游戏,减少工作线程数量后,性能能提升1 5 %。

再比如,Intel的P/E核心异构设计、AMD的非对称缓存架构,还有基于小芯片的CPU(比如AMD Zen系列),跨小芯片执行线程会导致高缓存抖动,增加延迟。

接下来,我给他列举了一些性能下降的常见原因和解决方案:
1 . 硬件性能瓶颈,比如高核心数CPU可能降低单核频率以控制功耗,导致关键线程性能不足。
解决方案是减少线程数量,提高活动核心的频率。

2 . 硬件资源争用,比如内存子系统压力、缓存效率降低。
解决方案是针对物理核心数量而非逻辑核心数量设置线程数,减少跨核心资源争用。

3 . 软件资源竞争,比如锁和原子操作延迟、错误共享。
解决方案是采用无锁定数据结构或细粒度锁,减少共享资源冲突。

4 . 操作系统调度问题,比如上下文交换开销、P/E核心调度优先级。
解决方案是使用QoS和线程优先级API将关键线程绑定到P核心,限制线程数量。

5 . 电源管理影响,比如核心停用算法。
解决方案是减少线程数量,使更多核心保持活动状态。

优化实践方法的话,我建议:
1 . 动态负载均衡,根据实时工作负载调整线程数量。

2 . 无锁定线程模型,适用于高并发场景,但实现起来可能有点复杂。

3 . 线程优先级与核心绑定,可以通过游戏配置文件来允许玩家或开发者自定义线程上限。

4 . 超线程测试与适配,低核心数系统可以启用超线程,高核心数系统则要禁用或限制线程在物理核心上运行。

最后,性能验证与调优也很重要,得用性能分析工具监测线程调度、缓存命中率和上下文切换次数,测试不同游戏场景下的线程数影响,通过Beta测试收集不同硬件配置下的性能数据,不断优化线程分配策略。

反正你看着办,根据你的具体情况来调整。
我还在想这个问题,看看还能不能找到更好的方法。

线程池有哪几个重要参数?

等等,我昨天调试那个电商促销系统的线程池的时候,卡壳了半天。
用户狂点秒杀按钮,服务器直接崩了。
后来发现是最大线程数设得太低了,一下子涌进来几百个请求,全部塞在工作队列里,新来的任务直接被拒绝,抛出异常。
客户那边就看到一堆“任务拒绝异常”。
我赶紧把最大线程数调到CPU核数的两倍,用无界队列,问题解决了。
但后来我又想,如果队列真的满了,那拒绝策略呢?是直接让线程自己跑掉,还是记录日志下次补上?这事儿挺复杂的。

线程池七大核心参数

核心线程数,就是线程池的基础兵力,平时不闲着,得随时待命。

最大线程数,就是线程池能调动的最大兵力,忙的时候还能扩军。

线程存活时间,就是那些临时工,闲着超过这个时间就滚蛋。

任务队列,就像仓库,任务先放这里,等有空位就处理。

线程优先级,就是给线程排个队,紧急任务先干。

拒绝策略,就是仓库满了,新货来了怎么办,要么扔掉,要么扔旧货。

线程工厂,就是造兵工厂,可以定制新兵的属性。