lowCoreThreadTimeOut || wc > corePoolSize;
?
if ((wc > maximumPoolSize || (timed && timedOut))
&& (wc > 1 || workQueue.isEmpty())) {
if (compareAndDecrementWorkerCount(c)) //若线程存活时间超时,则CAS减去线程数量
return null;
continue;
}
?
try {
Runnable r = timed ?
workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) : //允许超时回收则阻塞等待
workQueue.take(); //不允许则直接获取,没有就返回null
if (r != null)
return r;
timedOut = true;
} catch (InterruptedException retry) {
timedOut = false;
}
}
}
小结:getTask()方法主要功能;
-
实际在缓存队列中获取待执行的任务;
-
在这里管理线程是否要阻塞等待,控制线程的数量;
2.1.3.6、清理工作
private void processWorkerExit(Worker w, boolean completedAbruptly) {
if (completedAbruptly) // If abrupt, then workerCount wasn't adjusted
decrementWorkerCount();
?
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
completedTaskCount += w.completedTasks;
workers.remove(w); //移除执行完成的线程
} finally {
mainLock.unlock();
}
?
tryTerminate(); //每次回收完一个线程后都尝试终止线程池
?
int c = ctl.get();
if (runStateLessThan(c, STOP)) { //到这里说明线程池没有终止
if (!completedAbruptly) {
int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
if (min == 0 && ! workQueue.isEmpty())
min = 1;
if (workerCountOf(c) >= min)
return; // replacement not needed
}
addWorker(null, false); //异常终止线程的话,需要在常见一个线程
}
}
小结:processWorkerExit()方法主要功能;
-
真实完成线程池线程的回收;
-
调用尝试终止线程池;
-
保证线程池正常运行;
2.1.3.7、尝试终止线程池
final void tryTerminate() {
for (;;) {
int c = ctl.get();
//若线程池正在执行、线程池已终止、线程池还需要执行缓存队列中的任务时,返回
if (isRunning(c) ||
runStateAtLeast(c, TIDYING) ||
(runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty()))
return;
//执行到这里,线程池为SHUTDOWN且无待执行任务 或 STOP 状态
if (workerCountOf(c) != 0) {
interruptIdleWorkers(ONLY_ONE); //只中断一个线程
return;
}
?
//执行到这里,线程池已经没有可用线程了,可以终止了
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) { //CAS设置线程池终止
try {
terminated(); //执行钩子方法
} finally {
ctl.set(ctlOf(TERMINATED, 0)); //这里将线程池设为终态
termination.signalAll();
}
return;
}
} finally {
mainLock.unlock();
}
// else retry on failed CAS
}
}
小结:tryTerminate()方法主要功能;
-
实际尝试终止线程池;
-
终止成功则调用钩子方法,并且将线程池置为终态。
2.2、JAVA线程池总结
以上通过对JAVA线程池的具体分析我们可以看出,虽然流程看似复杂,但其实有很多内容都是状态重复校验、线程安全的保证等内容,其主要的功能与我们前面所提出的设计功能一致,只是额外增加了一些扩展,下面我们简单整理下线程池的功能;
2.2.1、主要功能
-
线程数量及存活时间的管理;
-
待处理任务的存储功能;
-
线程复用机制功能;
-
任务超量的拒绝功能;
2.2.2、扩展功能
-
简单的执行结果统计功能;
-
提供线程执行异常处理机制;
-
执行前后处理流程自定义;
-
提供线程创建方式的自定义;
2.2.3、流程总结
以上通过对JAVA线程池任务提交流程的分析我们可以看出,线程池执行的简单流程如下图所示;
2.3、JAVA线程池使用
线程池基本使用验证上述流程:
public static void main(String[] args) throws Exception {
//创建线程池
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
5, 10, 100, TimeUnit.SECONDS, new ArrayBlockingQueue(5));
//加入4个任务,小于核心线程,应该只有4个核心线程,队列为0
for (int i = 0; i < 4; i++) {
threadPoolExecutor.submit(new MyRunnable());
}
System.out.println("worker count = " + threadPoolExecutor.getPoolSize()); //worker count = 4
System.out.println("queue size = " + threadPoolExecutor.getQueue().size()); //queue size = 0
//再加4个任务,超过核心线程,但是没有超过核心线程 + 缓存队列容量,应该5个核心线程,队列为3
for (int i = 0; i < 4; i++) {
threadPoolExecutor.submit(new MyRunnable());
}
System.out.println("worker count = " + threadPoolExecutor.getPoolSize()); //worker count = 5
System.out.println("queue siz