线程池的参数设置

(1)corePoolSize:
核心线程数,核心线程会一直存活,即使没有任务需要处理。
当一个任务通过execute(Runnable)方法欲添加到线程池时:

  • 如果此时线程池中的线程数小于corePoolSize,即使线程池中的线程空闲,线程池也会优先创建新线程来处理任务,而不是直接交给现有的线程处理。
  • 如果此时线程池中的数量等于 corePoolSize,但是缓冲队列 workQueue未满,那么任务被放入缓冲队列。
  • 如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的线程数量小于maximumPoolSize,线程池也会创建新的线程来处理被添加的任务。
  • 如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量等于maximumPoolSize,那么通过handler所指定的策略来处理此任务。

所以线程池处理任务的优先级是: 核心线程池 >>> 等待序列 >>> 非核心线程池 >>> 拒绝或其他处理措施

allowCoreThreadTimeOut
如果为false(默认),则即使处于空闲状态,核心线程也保持活动状态。 如果为true,则核心线程使用keepAliveTime来超时等待工作。

(2)maximumPoolSize: 线程池中线程的最大数量

(3)keepAliveTime: 线程池维护线程所允许的空闲时间
当线程空闲时间达到keepAliveTime,该线程会退出,直到线程数量等于corePoolSize。如果线程空闲时间达到keepAliveTime,且allowCoreThreadTimeOut设置为true,则所有线程均会退出直到线程数量为0。

(4)unit: 线程池维护线程所允许的空闲时间的单位
(5)workQueue: 线程池所使用的缓冲队列
(6)handler: 线程池对拒绝任务的处理策略

handler有四个选择:
ThreadPoolExecutor.AbortPolicy(): 抛出java.util.concurrent.RejectedExecutionException异常
ThreadPoolExecutor.CallerRunsPolicy(): 重试添加当前的任务,他会自动重复调用execute()方法
ThreadPoolExecutor.DiscardOldestPolicy(): 抛弃旧的任务
ThreadPoolExecutor.DiscardPolicy(): 抛弃当前的任务

在这里插入图片描述
参数设置

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

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

缓冲队列长度设置过大,会导致任务响应时间过长,切忌以下写法:
LinkedBlockingQueue queue = new LinkedBlockingQueue();

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

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

keepAliveTime:
线程数量只增加不减少也不行。当负载降低时,可减少线程数量,如果一个线程空闲时间达到keepAliveTiime,该线程就退出。默认情况下线程池最少会保持corePoolSize个线程。

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

猜你喜欢

转载自blog.csdn.net/qq_42848910/article/details/107945596