Java线程池参数详解

JDK1.5中引入了强大的concurrent包,其中最经常使用的莫过了线程池的实现ThreadPoolExecutor,它给咱们带来了极大的方便,但同时,对于该线程池不恰当的设置也可能使其效率并不能达到预期的效果,甚至仅至关于或低于单线程的效率。线程

ThreadPoolExecutor类可设置的参数主要有:队列

 

  • corePoolSize

 

核心线程数,核心线程会一直存活,即便没有任务须要处理。当线程数小于核心线程数时,即便现有的线程空闲,线程池也会优先建立新线程来处理任务,而不是直接交给现有的线程处理。ci

核心线程在allowCoreThreadTimeout被设置为true时会超时退出,默认状况下不会退出。it

 

  • maxPoolSize
当线程数大于或等于核心线程,且任务队列已满时,线程池会建立新的线程,直到线程数量达到maxPoolSize。若是线程数已等于maxPoolSize,且任务队列已满,则已超出线程池的处理能力,线程池会拒绝处理任务而抛出异常。

 

  • keepAliveTime

 

当线程空闲时间达到keepAliveTime,该线程会退出,直到线程数量等于corePoolSize。若是allowCoreThreadTimeout设置为true,则全部线程均会退出直到线程数量为0。效率

 

  • allowCoreThreadTimeout

是否容许核心线程空闲退出,默认值为false。线程池

  • queueCapacity

任务队列容量。从maxPoolSize的描述上能够看出,任务队列的容量会影响到线程的变化,所以任务队列的长度也须要恰当的设置。queue

 

线程池按如下行为执行任务im

 

  1. 当线程数小于核心线程数时,建立线程。
  2. 当线程数大于等于核心线程数,且任务队列未满时,将任务放入任务队列。
  3. 当线程数大于等于核心线程数,且任务队列已满
    1. 若线程数小于最大线程数,建立线程
    2. 若线程数等于最大线程数,抛出异常,拒绝任务

 

 

系统负载异常

参数的设置跟系统的负载有直接的关系,下面为系统负载的相关参数:时间

 

  • tasks,每秒须要处理的最大任务数量
  • tasktime,处理第个任务所须要的时间
  • responsetime,系统容许任务最大的响应时间,好比每一个任务的响应时间不得超过2秒。

 

 

参数设置

 

corePoolSize:

每一个任务须要tasktime秒处理,则每一个线程每钞可处理1/tasktime个任务。系统每秒有tasks个任务须要处理,则须要的线程数为:tasks/(1/tasktime),即tasks*tasktime个线程数。假设系统每秒任务数为100~1000,每一个任务耗时0.1秒,则须要100*0.1至1000*0.1,即10~100个线程。那么corePoolSize应该设置为大于10,具体数字最好根据8020原则,即80%状况下系统每秒任务数,若系统80%的状况下第秒任务数小于200,最多时为1000,则corePoolSize可设置为20。

 

queueCapacity:

任务队列的长度要根据核心线程数,以及系统对任务响应时间的要求有关。队列长度能够设置为(corePoolSize/tasktime)*responsetime: (20/0.1)*2=400,即队列长度可设置为400。

队列长度设置过大,会致使任务响应时间过长,切忌如下写法:

LinkedBlockingQueue queue = new LinkedBlockingQueue();

这其实是将队列长度设置为Integer.MAX_VALUE,将会致使线程数量永远为corePoolSize,不再会增长,当任务数量陡增时,任务响应时间也将随之陡增。

 

maxPoolSize:

当系统负载达到最大值时,核心线程数已没法按时处理完全部任务,这时就须要增长线程。每秒200个任务须要20个线程,那么当每秒达到1000个任务时,则须要(1000-queueCapacity)*(20/200),即60个线程,可将maxPoolSize设置为60。

 

keepAliveTime:

线程数量只增长不减小也不行。当负载下降时,可减小线程数量,若是一个线程空闲时间达到keepAliveTiime,该线程就退出。默认状况下线程池最少会保持corePoolSize个线程。

 

allowCoreThreadTimeout:

默认状况下核心线程不会退出,可经过将该参数设置为true,让核心线程也退出。

 

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

相关文章
相关标签/搜索