题记

我想不管是在面试中、还是工作中,我们总会面临这种问题,那么到底有没有一种计算公式去告诉我们如何去配置呢?

答案是:没有

想要合理的配置线程池参数,首先我们需要明白我们的任务是计算型还是IO密集型以及和CPU核数之间的关系。

Java并发编程实战

该书中推荐的计算方式

线程数 = CPU 核心数 *(1+平均等待时间/平均工作时间)

我觉得将这个公式转换一下更好理解

线程数 = CPU 核心数 *(平均等待时间 + 平均工作时间)/ 平均工作时间)

怎么理解这个公式,我举一个场景

我这有个索引服务需要组装数据并录入到es中,组装数据期间我可能需要去查询Hbase、Redis等多数据源,假设CPU核心数为8、查询Hbase需要2ms、Redis需要2ms,代码中涉及的一些计算(逻辑判断、json转换等)时间需要2ms,录入数据到ES(期间需要建立连接、数据包传送)需要4ms,套用上面的公式我的平均等待时间是2ms+2ms+4ms=10ms,平均工作时间(计算时间)2ms,处理一条数据花费的总时间为12ms,线程数:8*12/2=48个线程

上述这种方式太偏理论,但是实际我们的业务需要花费的时间去细分,这种方式适合用于RPC框架调用、各个业务逻辑计算上报打点并且监控到位的情况下我们能确切知道各个时间点,但是实际情况很难做到。

美团技术团队

以下文章摘选自美团技术团队的博客,看了这么多篇文章,感觉这里面总结的是最好的,固记之。

追求参数设置合理性

有没有一种计算公式,能够让开发同学很简易地计算出某种场景中的线程池应该是什么参数呢?

带着这样的疑问,我们调研了业界的一些线程池参数配置方案:
在这里插入图片描述
调研了以上业界方案后,我们并没有得出通用的线程池计算方式。并发任务的执行情况和任务类型相关,IO密集型和CPU密集型的任务运行起来的情况差异非常大,但这种占比是较难合理预估的,这导致很难有一个简单有效的通用公式帮我们直接计算出结果。

线程池参数动态化

尽管经过谨慎的评估,仍然不能够保证一次计算出来合适的参数,那么我们是否可以将修改线程池参数的成本降下来,这样至少可以发生故障的时候可以快速调整从而缩短故障恢复的时间呢?基于这个思考,我们是否可以将线程池的参数从代码中迁移到分布式配置中心上,实现线程池参数可动态配置和即时生效,线程池参数动态化前后的参数修改流程对比如下:

在这里插入图片描述
基于以上三个方向对比,我们可以看出参数动态化方向简单有效。

美团还提供了动态配置线程池参数、监控架构,感兴趣同学可以去仔细看看。

传送门:Java线程池实现原理及其在美团业务中的实践

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐