//线程工厂
private volatile ThreadFactory threadFactory;
//任务拒绝策略
private volatile RejectedExecutionHandler handler;
//线程存活时间
private volatile long keepAliveTime;
//是否允许核心线程超时
private volatile boolean allowCoreThreadTimeOut;
//核心池大小,若allowCoreThreadTimeOut被设置,核心线程全部空闲超时被回收的情况下会为0
private volatile int corePoolSize;
//最大池大小,不得超过CAPACITY
private volatile int maximumPoolSize;
//默认的任务拒绝策略
private static final RejectedExecutionHandler defaultHandler = new AbortPolicy();
//运行权限相关
private static final RuntimePermission shutdownPerm =
new RuntimePermission("modifyThread");
...
}
小结一下:以上线程池的设计可以看出,线程池的功能还是很完善的。
-
提供了线程创建、数量及存活时间等的管理;
-
提供了线程池状态流转的管理;
-
提供了任务缓存的各种容器;
-
提供了多余任务的处理机制;
-
提供了简单的统计功能;
2.1.2、线程池构造函数
//构造函数
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.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
小结一下:
- 构造函数告诉了我们可以怎样去适用线程池,线程池的哪些特性是我们可以控制的;
2.1.3、线程池执行
2.1.3.1、提交任务方法
? public void execute(Runnable command);
? Future<?> submit(Runnable task);
? Future submit(Runnable task, T result);
? Future submit(Callable task);
public Future<?> submit(Runnable task) {
if (task == null) throw new NullPointerException();
RunnableFuture<Void> ftask = newTaskFor(task, null);
execute(ftask);
return ftask;
}
可以看到submit方法的底层调用的也是execute方法,所以我们这里只分析execute方法;
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
int c = ctl.get();
//第一步:创建核心线程
if (workerCountOf(c) < corePoolSize) { //worker数量小于corePoolSize
if (addWorker(command, true)) //创建worker
return;
c = ctl.get();
}
//第二步:加入缓存队列
if (isRunning(c) && workQueue.offer(command)) { //线程池处于RUNNING状态,将任务加入workQueue任务缓存队列
int recheck = ctl.get();
if (! isRunning(recheck) && remove(command)) //双重检查,若线程池状态关闭了,移除任务
reject(command);
else if (workerCountOf(recheck) == 0) //线程池状态正常,但是没有线程了,创建worker
addWorker(null, false);
}
//第三步:创建临时线程
else if (!addWorker(command, false))
reject(command);
}
小结一下:execute()方法主要功能:
-
核心线程数量不足就创建核心线程;
-
核心线程满了就加入缓存队列;
-
缓存队列满了就增加非核心线程;
-
非核心线程也满了就拒绝任务;
2.1.3.2、创建线程
private boolean addWorker(Runnable firstTask, boolean core) {
retry:
for (;;) {
int c = ctl.get();
int rs = runStateOf(c);
?
//等价于:rs>=SHUTDOWN && (rs != SHUTDOWN || firstTask != null || workQueue.isEmpty())
//线程池已关闭,并且无需执行缓存队列中的任务,则不创建
if (rs >= SHUTDOWN &&
! (rs == SHUTDOWN &&
firstTask == null &&
! workQueue.isEmpty()))
return false;
?
for (;;) {
int wc = workerCountOf(c);
if (wc >= CAPACITY ||
wc >= (core ? corePoolSize : maximumPoolSize))
return false;
if (compareAndIncrementWorkerC