vlambda博客
学习文章列表

线程池参数及合理设置

一、线程池的7大核心参数

1. corePoolSize 

            核心线程数目核心线程会一直存活,及时没有任务需要执行当线程数小于核心线程数时,即使有线程空闲,线程池也会优先创建新线程处理设置allowCoreThreadTimeout=true(默认false)时,核心线程会超时关闭

2. maximumPoolSize 最大线程数目

        当空闲线程时间达到 keepAliveTime线程会关闭直到数量等于corePoolSize

3. keepAliveTime空闲时间

4. unit 时间单位 

         超过核心线程的生存时间单位,如秒、毫秒等。

5. workQueue 阻塞队列

        LinkedBlockingQueue无界队列容量Integer.MAX_VALUE,FixedThreadPool 和 SingleThreadExecutor 线程池的线程数是固定的,用的就是LinkedBlockingQueue

        SynchronousQueue:直接提交的任务队列CachedThreadPool 的最大线程数是 Integer.MAX_VALUE,用的是SynchronousQueue

        ArrayBlockingQueue:指定队列大小corePoolSize >队列>maximumPoolSize 

6. threadFactory 线程工厂

             可以定制线程对象的创建,例如设置线程名字、是否是守护线程等。

7. handler 拒绝策略

        AbortPolicy终止策略超过最大承载执行拒绝任务时,会直接抛出一个类型为RejectedExecutionException 的 RuntimeException异常

        CallerRunsPolicy调用者执行策略超过承载执行策略时调用者线程执行任务

        DiscardOldestPolicy丢弃最早任务策略超过承载丢弃队列中最早的任务若线程池关闭则舍弃

        DiscardPolicy丢弃策略超过承载丢弃任务

        实现RejectedExecutionHandler接口自定义策略

二、线程池参数的合理设置

Ø tasks,程序每秒需要处理的最大任务数量

Ø tasktime,单线程处理一个任务所需要的时间

Ø responsetime,系统允许任务最大的响应时间

corePoolSize

每个任务需要tasktime秒处理,则每个线程每秒可处理1/tasktime个任务。系统每秒有tasks个任务需要处理,则需要的线程数为:tasks/(1/tasktime)tasks*tasktime个线程数。具体数字最好根据8020原则,即80%情况下系统每秒任务数

queueCapacity:任务队列的长度

        任务队列的长度要根据核心线程数,以及系统对任务响应时间的要求有关。队列长度可以设置为(corePoolSize/tasktime)responsetime

maxPoolSize:最大线程数

        当系统负载达到最大值时,核心线程数已无法按时处理完所有任务,这时就需要增加线程。每秒200个任务需要20个线程,那么当每秒达到1000个任务时,则需要(1000-queueCapacity)*(20/200)

keepAliveTime

        keepAliveTiime设定值可根据任务峰值持续时间来设定。


以上关于线程数量的计算并没有考虑CPU的情况。若结合CPU的情况,比如,当线程数量达到50时,CPU达到100%,则将maxPoolSize设置为60也不合适,此时若系统负载长时间维持在每秒1000个任务,则超出线程池处理能力,应设法降低每个任务的处理时间(tasktime)