ThreadPoolExecutor是阿里推荐使用的线程池工具,主要是为了更方便控制参数,不推荐Executors创建线程池是因为容易内存溢出(OOM)
部分源码:
public ThreadPoolExecutor(int corePoolSize, // 核心线程数
int maximumPoolSize, // 最大线程数
long keepAliveTime, // 非核心线程最大空闲时间
TimeUnit unit, // 时间单位
BlockingQueue<Runnable> workQueue, // 工作线程队列, 其长度不是固定的, 根据线程数相关参数计算而来
ThreadFactory threadFactory, // 创建线程的工厂
RejectedExecutionHandler handler) { // 拒绝策略
// ...
}
线程池管理线程的好处在于可以节约创建和销毁线程的时间,因此线程池更适合用在任务执行时间短且任务数量大的场景。
提交任务:
public void execute(); //提交任务无返回值
public Future<?> submit(); //任务执行完成后有返回值
监控线程池:
public long getTaskCount(); //线程池已执行与未执行的任务总数
public long getCompletedTaskCount(); //已完成的任务数
public int getPoolSize(); //线程池当前的线程数
public int getActiveCount(); //线程池中正在执行任务的线程数量
ThreadPoolExecutor的工作原理:
- 在核心线程数未达到
corePoolSize
时,优先创建核心线程,而不是复用线程 - 核心线程全部创建的情况下,如果线程池无法及时处理提交的任务,优先将任务放入
WorkQueue
排队等待,而不是创建非核心线程 - 当核心线程达到
corePoolSize
且WorkQueue
队列已满,线程池开始创建非核心线程 - 如果程序提交的任务完全超过线程池的处理能力(线程数达
maximumPoolSize
且WordQueue
满),会触发线程池的拒绝策略
拒绝策略:
-
AbortPolicy
(default): 抛出异常RejectedExecutionException
-
CallerRunsPolicy
: 该任务交由提交任务的线程执行 -
DiscardOldestPolicy
: 丢弃老的任务,即队列头部任务,不会抛异常 -
DiscardPolicy
: 丢弃要提交的任务,不会抛异常