问:谈谈你对 java 线程池 ThreadPoolExecutor 与 ScheduledThreadPoolExecutor 的理解及相关构造参数的含义?
答:线程池由任务队列和工作线程组成,它可以重用线程来避免线程创建的开销,在任务过多时通过排队避免创建过多线程来减少系统资源消耗和竞争,确保任务有序完成;
ThreadPoolExecutor 继承自 AbstractExecutorService,实现了 ExecutorService 接口;
ScheduledThreadPoolExecutor 继承自 ThreadPoolExecutor,实现了 ExecutorService 和 ScheduledExecutorService 接口;
ThreadPoolExecutor 构造函数如下:
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.acc = System.getSecurityManager() == null ?
null :
AccessController.getContext();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
参数名 | 作用 |
---|---|
corePoolSize | 线程池中所保存的核心线程数。 |
maximumPoolSize | 线程池允许创建的最大线程数。 |
keepAliveTime | 当前线程池线程总数大于核心线程数时,终止多余的空闲线程的时间。 |
unit | keepAliveTime 参数的时间单位,可选值有毫秒、秒、分等。 |
workQueue | 任务队列,如果当前线程池达到核心线程数 corePoolSize,且当前所有线程都处于活动状态时,则将新加入的任务放到此队列中。 |
threadFactory | 线程工厂,让用户可以定制线程的创建过程,通常不需设置。 |
Handler | 拒绝策略,当线程池与 workQueue 队列都满了的情况下,对新加任务采取的处理策略。 |
线程池启动后默认是空的,只有任务来临才会创建线程以处理请求。prestartAllCoreThreads 方法可以让线程池启动后立即启动所有核心线程以等待任务。
-
任务数量小于 corePoolSize,则立即创建新线程来处理任务;
任务数量大于 corePoolSize,但小于 maximumPoolSize,则将任务放进 workQueue,当阻塞队列满时才创建新线程;
如果 corePoolSize 与 maximumPoolSize 相同,则创建了固定大小的线程池。