如何据业务需求设置ThreadPoolExecutor线程池参数

1. 简介

常用的线程池有newFixedThreadPool,newCachedThreadPool,newSingleThreadScheduledExecutor,newScheduledThreadPool但其实这些线程池都是根据ThreadPoolExecutor传入不同的参数构造而成的,如果我们能明白这些参数的含义就能创建一个更贴合当前的业务场景的线程池了。

2. 参数解析

  1. corePoolSize
    核心线程数,即使没有任务需要执行这些线程也一不会回收,当有任务需要执行时优先使用这些线程。
  2. maximumPoolSize
    最大线程数,当执行完任务后一定时间会回收(根据这个参数keepAliveTime设置回收时间)。
  3. workQueue
    任务队列,当核心线程用完的时候任务方法任务队列中排队等待。
  4. handler
    拒绝策略,当corePoolSize,workQueue,maximumPoolSize都达到最大值的时候会调用拒绝策略。
  5. keepAliveTime
    线程存活时间。

3. 使用

在使用前先了解下执行任务时的顺序
1,当线程数小于核心线程数时,创建线程。
2,当线程数大于等于核心线程数,且任务队列未满时,将任务放入任务队列。
3,当线程数大于等于核心线程数,且任务队列已满和最大线程数未满时,创建线程。
4,若线程数等于最大线程数,调用拒绝策略。

在使用线程池先我们先要统计系统的一些数据

  • tasks:每秒任务数的范围,500-2000个任务
  • tasksMax:最大任务数,2000
  • tasksCommon:系统在百分之80的时间的任务数,800
  • responsetime:系统的最大响应时间,2秒
  • taskTime:每个任务的执行时间,0.1秒
3.1 corePoolSize

由于这些线程都是会缓存的,如果能使得系统在大部分时间内只需要用到核心线程,那么就能保证性能最大化。

corePoolSize = tasksCommon * taskTime = 800 * 0.1 = 80 // 在日常的大部分时间只要80个核心线程就能处理每秒800个任务。

3.2 workQueue

当核心线程来不及处理任务时,可以把任务先放到任务队列里。但如果队列过长会导致任务堆积在队列里并等待核心线程空闲,而不会创建非核心线程。

workQueue = corePoolSize / taskTime * (responsetime - taskTime) = 80 / 0.1 * (2 - 0.1) = 1520 // 需要保证队列里的剩余任务要保证在responsetime内运行完成,而由于核心线程还在运行着任务所以需要用responsetime-taskTime=2s-0.1s=1.9s。

3.3 maximumPoolSize

此参数通常用来应付82原则里面2的情况,少部分时间内大量任务请求的情况,保证了系统的快速响应。

maximumPoolSize = tasksMax * taskTime = 2000 * 0.1 = 200

4. 实际使用中遇到的坑

4.1 任务执行顺序

参数: corePoolSize-3,workQueue-3,maximumPoolSize-7
任务:task1-task10
具体步骤:按顺序把10个任务提交到线程池,task1-task3在核心线程运行,task4-task6放到任务队列,task7-task10在非核心线程池运行,当核心线程池空闲后回到任务队列中取出任务并运行。
结果顺序:task1,task2,task3,task7,task8,task9,task10,task4,task5,task6

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值