一、聊聊线程池的参数配置规则
1、CPU密集型、IO密集型、混合型任务
2、任务执行时间
3、任务是否有依赖----比如其他系统资源(数据库,第三方接口等)
这里讲解,根据CPU密集型、IO密集型、任务执行时间来决定如何配置:核心线程数、最大线程数、等待队列数
1、CPU密集型:一般使用较小的线程池---》 CPU核心数+1
2、IO密集型:2*CUP核心数+1
3、任务执行时间(系统任务吞吐量、任务执行完成需要时间等考虑)
那么就需要以下几个参数来决定核心线程数、最大线程数、等待队列数的具体参考范围
taskSecond=20~100 //每秒系统接收的任务数量:参考我的业务系统大概是20~100个
taskCost=5~10 //每个任务需要花费的时间(单位:秒):这里参考我的文件处理业务系统是:5s~10s
responseTime=1 //系统允许容忍最大响应时间,这里1秒,其实我的业务系统是异步处理,所以基本是毫秒级别响应,但是为了保守起见,为1秒吧
那么我们开始根据这几个服务器的参考参数来计算一下核心线程数、最大线程数、等待队列数的取值范围
- 核心线程池数=corePoolSize=每秒需要多少个线程来处理,所以有了下面的公式:(公式的值是一个范围,大伙看不懂记得在纸上写出来就看得通熟易懂)
1、corePoolSize=taskSecond / ( 1 / taskCost )=(20~100)/(1/5~10)=(20~100)* (5~10)=(100~500)~(200~1000) 。也就是corePoolSize说明:
5秒内可能产生的任务是:100~500
10秒内可能产生的任务数量数:200~1000
2、但是根据8020原则,如果80%的每秒任务小于800,那么corePoolSize设置为80即可。
注意:但是我的当时为什么考虑没有根据自己计算出来的参数,主要是我的是文件处理,处理时间过长,最大的文件上限时:100M,当时文件分片上传,默认是5M一片,那么最长时间是涉及20分片文件进行下载,
再接着上传到第三方接口。那么考虑点来了:上面参考我自己的业务系统10~15秒处理完成一个任务,那么最坏的情况是:文件下载,上传各占50%的时间,此刻: 按照上面8020原则:(5秒~10秒)*80=400~800个任务。那么针对上面计算出来的: 5秒内任务数量,8020原则比对在范围内:100<400<500 10秒内任务最量,8020原则比对在范围内:200<800<1000 所以我自己设置:corePoolSize=80
- 等待队列数=queuePoolSize=(corePoolSize / taskCose) * responseTime
代入数据maxPoolSize=(80/5~10)*1=16~8,也就是说,queuePoolSize的取值范围是8~16,意思是等待队列里面的线程,可以等待8~16秒,超过了这个时间就需要开新的线程来执行。
- 最大线程池数=maxPoolSize=(max(taskSecond) - queuePoolSize) / (1 / taskCost)=(100-(8~6)) / (1/5~10) = (92~94) / ( 1/ 5~10) =(92~94)* (5~10)=(92*5)~(94*10)=460~940
最大线程数=( 最大任务数-等待队列容量)/ 每个线程每秒处理能力