美文网首页
线程池配置规则

线程池配置规则

作者: _micang | 来源:发表于2019-11-22 16:20 被阅读0次

    https://blog.csdn.net/xiang__liu/article/details/82796543

    1. 线程池配置规则:  线程池大小=CPU个数 * CPU期望利用率 * (1 + 任务等待时间 / 任务处理时间)

    线程池的理想大小取决于被提交任务的类型以及所部署系统的特性。线程池应该避免设置的过大或过小,如果线程池过大,大量的线程将在相对很少的CPU和内存资源上发生竞争,这不仅会导致更高的内存使用量,而且还可能耗尽资源。如果线程池过小,那么将导致许多空闲处理器无法执行任务,降低了系统吞吐率。

    要正确设置线程池的大小,必须分析计算环境、资源预算和任务特性。包括所部署系统的CPU个数、内存大小、任务类型(计算密集、IO密集等)。如果待处理任务行为特征差异较大,那应该考虑使用多个线程池,分别处理不同类任务。大致上来说,对于计算密集型任务线程池大小和CPU个数相近通常能实现最优利用率;对于IO密集型任务,由于线程不会一直执行,所以线程吃的规模应该更大。要正确设置线程池大小,需要估算出任务的等待时间(任务从提交到结束耗时)和处理时间(实际处理耗时)的比值。

    要是处理器达到期望的使用率,线程池的最优大小等于:

    线程池大小=CPU个数 * CPU期望利用率 * (1 + 任务等待时间 / 任务处理时间)

    假设有一个定时解析大文件并存入数据库的任务,系统部署在8核服务器上,期望定时任务执行CPU占比约20%,任务平均等待时间为150ms,任务平均处理时间为50ms

    线程池最优大小=8*0.2*(1+150/50)=3

    三、如何设置参数

    默认值

    corePoolSize=1

    queueCapacity=Integer.MAX_VALUE

    maxPoolSize=Integer.MAX_VALUE

    keepAliveTime=60s

    allowCoreThreadTimeout=false

    rejectedExecutionHandler=AbortPolicy()

    如何来设置

    需要根据几个值来决定

    tasks :每秒的任务数,假设为500~1000

    taskcost:每个任务花费时间,假设为0.1s

    responsetime:系统允许容忍的最大响应时间,假设为1s

    做几个计算

    corePoolSize = 每秒需要多少个线程处理? 

    threadcount = tasks/(1/taskcost) =tasks*taskcout =  (500~1000)*0.1 = 50~100 个线程。corePoolSize设置应该大于50

    根据8020原则,如果80%的每秒任务数小于800,那么corePoolSize设置为80即可

    queueCapacity = (coreSizePool/taskcost)*responsetime

    计算可得 queueCapacity = 80/0.1*1 = 80。意思是队列里的线程可以等待1s,超过了的需要新开线程来执行

    切记不能设置为Integer.MAX_VALUE,这样队列会很大,线程数只会保持在corePoolSize大小,当任务陡增时,不能新开线程来执行,响应时间会随之陡增。

    maxPoolSize = (max(tasks)- queueCapacity)/(1/taskcost)

    计算可得 maxPoolSize = (1000-80)/10 = 92

    (最大任务数-队列容量)/每个线程每秒处理能力 = 最大线程数

    rejectedExecutionHandler:根据具体情况来决定,任务不重要可丢弃,任务重要则要利用一些缓冲机制来处理

    keepAliveTime和allowCoreThreadTimeout采用默认通常能满足

    以上都是理想值,实际情况下要根据机器性能来决定。如果在未达到最大线程数的情况机器cpu load已经满了,则需要通过升级硬件(呵呵)和优化代码,降低taskcost来处理。

    相关文章

      网友评论

          本文标题:线程池配置规则

          本文链接:https://www.haomeiwen.com/subject/xruhvctx.html