ThreadPoolExecutor用法总结

Java的ThreadPoolExecutor是很常用的线程池,其构造如下:

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) 

在JDK携带的源码注释中可以很明确的看到各个参数的含义:
corePoolSize:保持在池中的线程数量,如果没有设置allowCoreThreadTimeout参数,即使这些线程空闲也将一直保持在池中
maximumPoolSize:线程池中的最大线程数量
keepAliveTime:当线程池中空闲线程数量超过corePoolSize时,多余的线程会超过这个保活时间会被销毁;
unit:keepAliveTime的单位
workQueue:任务队列,被添加到线程池中,但尚未被执行的任务;它一般分为直接提交队列、有界任务队列、无界任务队列、优先任务队列几种;
threadFactory:线程工厂,用于创建线程,一般用默认即可;
handler:拒绝策略;当任务太多来不及处理时,如何拒绝任务,有4个策略:

  • ThreadPoolExecutor.AbortPolicy():抛出java.util.concurrent.RejectedExecutionException异常
  • ThreadPoolExecutor.CallerRunsPolicy:直接在 execute 方法的调用线程中运行被拒绝的任务;如果执行程序已关闭,则会丢弃该任务
  • ThreadPoolExecutor.DiscardOldestPolicy():丢弃最老的任务
  • ThreadPoolExecutor.DiscardPolicy:丢弃当前任务

当通过execute提交任务执行时:

  • 如果当前线程数量小于corePoolSize,创建新的线程处理任务
  • 如果当前线程数量等于corePoolSize,任务加入workQueue队列
  • 如果线程池中数量大于等于corePoolSize,workQueue队列满,线程数量小于maximumPoolSize,创建新的线程处理任务
  • 如果线程池中线程数量等于maximumPoolSize,workQueue队列也满,根据handler指定的策略处理任务
  • 如果线程池中线程数量大于corePoolSize,空闲线程超过keepAliveTime,线程将被终止

因此,当并发任务提交时,
一开始,并发量不大,少量线程(<=corePoolSize)可以处理时,此时workQueue为空,线程池中线程数量<=corePoolSize
并发量继续增大,少量线程已经处理不了时,任务入队列,继续用corePoolSize数量的线程处理任务;
如果并发量没有变化,一直持续,队列一直累积,直到队列满,创建新的线程处理任务
如果并发量不是很大,创建的新的线程在完成新任务之后还能处理队列中的任务,那么队列会逐渐减少,直至为0,然后线程池中的线程也会有空闲,终止,最终线程数量降下来
如果并发量很大,创建新的线程也处理不过来,那么这时候就会出现线程池满,队列也满的情况,此时就会按照拒绝策略进行处理。

特殊情况:

  • corePoolSize为0时怎么处理?默认会起一个线程进行处理。
  • 队列容量为空怎么处理?意味着一旦线程数量达到corePoolSize,就要new新线程处理任务,达到maximumPoolSize,就要按照拒绝策略进行处理
  • 队列容量为无限大怎么处理?意味着队列永远不会满(直到内存不足崩溃),永远用corePoolSize数量的线程处理任务,如果处理不过来的话,队列就会一直增长直到崩溃

你可能感兴趣的:(Java)