继承了AbstractExecutorService(抽象类)
该抽象类实现了ExecutorService 接口
该接口又继承于Executor接口
Executor接口只有一个方法void execute(Runnable command);
Executor是一个顶层接口,其唯一的方法用来执行runnable任务;
ExecutorService接口继承于Executor,并声明了一些submit,invokeAll,invokeAny及shutdown方法。主要是负责线程的一些操作。
AbstractExecutorService基本实现了executorService中的方法, 线程池又继承了aes。
核心参数:
corePoolSize: 核心池大小,默认情况下线程不会超过核心大小。
maximumPoolSize: 最大线程数, 当达到一定负载时,线程数会超过核心数,但始终小于最大线程数. 当负载较轻会回收线程至核心池数量
keepAliveTime: 表示线程没有任务执行时,的存活时间. 默认情况,当线程数大于核心小于最大数量时才会启用; 如果调用allowCoreThreadTimeOut(boolean)方法,线程数下界为0
unit:keepAliveTime的时间单位
workQueue: 阻塞队列,用来存储等待执行的任务。 一般很少使用abq和pbq,多用lbq和synchronousQueue.队列.
abq: arrayBlockingQueue队列,基于数组的先进先出,创建时必须指定大小
pbq: PriorityBlockingQueue 优先级队列
lbq: linkedBlockingQueue,基于链表的队列,默认长度为Integer.MAX_VALUE
synchronousQueue: 不保存任务,直接创建新线程
threadFactory:线程工厂
handler: 对拒绝任务的处理策略,四种参数. abortPolicy(丢弃任务并抛异常),discardPolicy(丢弃任务不抛异常),DiscardOldestPolicy(丢弃最前面的任务),callerRunsPolicy(交由调用线程处理)
运行时参数:
workers: 工作集
allowCoreThreadTimeOut: 是否允许核心线程设置存活时间
poolSize: 线程池中当前线程数
largestPoolSize: 记录曾经出现过的最大线程数
completedTaskCount: 记录已经执行完的任务数
线程池的四种状态:
running : 0 创建线程池后
shutdown : 1 调用了shutdown()方法,此时线程池无法接受新任务
stop : 2 调用shutdownNow()方法,无法接受新任务并尝试终止现有任务
terminated : 3 所有工作线程销毁并且任务缓冲队列清空后的状态
常见线程池:
// 实际采用的linkedBlockingQueue,缓存队列,threadNum既是核心线程数也是最大线程数。
ExecutorService pool = Executors.newFixedThreadPool(threadNum);
// 可缓存线程池,实际采用synchronousQueue队列,最大线程数为Integer.MAX_VALUE
ExecutorService pool = Executors.newCachedThreadPool();
// 单线程线程池,只有核心线程和最大线程都为1
ExecutorService pool = Executors.newSingleThreadExecutor();
// 延迟线程池,可实现delay接口,可以延迟或按周期执行。参数为核心线程池数
ExecutorService pool = Executors.newScheduledThreadPool(threadNum);
构造函数:
线程池构造函数: 实际都是指向最后一个构造函数;
// 真正的执行构造函数
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; // 任务拒绝策略
}
线程池接收新任务的执行流程图 :
文字版:
来一个新任务, 如果目前线程池的线程数量小于核心线程数,则创建一个新线程并执行该任务.;
如果目前线程数大于核心数量,则尝试添加到缓存队列中,如果缓存队列满了则新创建线程并执行.
如果线程数量已达到最大且缓存队列满了,则按照策略拒绝任务
流程图版:
流程图里的please/just wait和 分配线程,线程执行的具体策略和出现的问题会根据 不同种类的线程池、采取的策略问题而不同。
线程池一些源码:
public void execute(Runnable command) {
if (command == null) //任务不能为空
throw new NullPointerException();
if (poolSize >= corePoolSize || !addIfUnderCorePoolSize(command)) {
/*
此时判断未加锁,判断核心线程数和当前线程数的关系,如果数目小于核心线程则直接去创建线程并执行.所以返回true,取!的目的是,说明如果不能创建新线程,则保证任务放入队列中
*/
if (runState == RUNNING && workQueue.offer(command)) {
//判断线程池状态并且将任务放入任务队列中
if (runState != RUNNING || poolSize == 0)
//再次确认状态,确保线程池可以处理任务,防止shutdown的调用
ensureQueuedTaskHandled(command);//确保任务放入队列中
} else if (!addIfUnderMaximumPoolSize(command)) {
//判断当前线程数和最大线程数的关系,如果达到最大则拒绝任务(根据之前参数的选择)
reject(command); // is shutdown or saturated
}
}
}
private void ensureQueuedTaskHandled(Runnable command) {
// 如果当前状态不是RUNING,则当前任务不加入到任务队列中,判断如果状态是停止,线程数小于允许的最大数,且任务队列还不空
if (state < STOP &&
poolSize < Math.max(corePoolSize, 1) &&
!workQueue.isEmpty())
//则加入一个新的工作线程到线程池来帮助处理还未处理完的任务
t = addThread(null);
if (reject)
reject(command);
}
private boolean addIfUnderCorePoolSize(Runnable firstTask) {
Thread t = null;
final ReentrantLock mainLock = this.mainLock;
mainLock.lock(); //上锁
try {
if (poolSize < corePoolSize && runState == RUNNING) //线程数小于核心数,则添加新的线程并执行任务
t = addThread(firstTask); //创建线程去执行firstTask任务
} finally {
mainLock.unlock();
}
if (t == null) //创建失败
return false;
t.start(); //启动线程
return true;
}
private Thread addThread(Runnable firstTask) {
Worker w = new Worker(firstTask);
Thread t = threadFactory.newThread(w); //创建一个线程,执行任务
if (t != null) {
w.thread = t; //将创建的线程的引用赋值为w的成员变量
workers.add(w);
int nt = ++poolSize; //当前线程数加1
if (nt > largestPoolSize) //更新最大线程数记录
largestPoolSize = nt;
}
return t;
}
Worker 类
private final class Worker implements Runnable { //说明是个线程
private final ReentrantLock runLock = new ReentrantLock();
private Runnable firstTask;
volatile long completedTasks;
Thread thread;
Worker(Runnable firstTask) {
this.firstTask = firstTask;
}
boolean isActive() { //判断是否可以自由/活跃,为true说明已上锁
return runLock.isLocked();
}
void interruptIfIdle() {
final ReentrantLock runLock = this.runLock;
if (runLock.tryLock()) {
try {
if (thread != Thread.currentThread())
thread.interrupt();
} finally {
runLock.unlock();
}
}
}
void interruptNow() {
thread.interrupt();
}
private void runTask(Runnable task) {
final ReentrantLock runLock = this.runLock;
runLock.lock();//上锁
try {
if (runState < STOP &&
Thread.interrupted() &&
runState >= STOP)
boolean ran = false;
beforeExecute(thread, task); //beforeExecute方法是ThreadPoolExecutor类的一个方法,没有具体实现,用户可以根据
//自己需要重载这个方法和后面的afterExecute方法来进行一些统计信息,比如某个任务的执行时间等
try {
task.run();
ran = true;
afterExecute(task, null);
++completedTasks;
} catch (RuntimeException ex) {
if (!ran)
afterExecute(task, ex);
throw ex;
}
} finally {
runLock.unlock();
}
}
public void run() {
try {
Runnable task = firstTask;
firstTask = null;
while (task != null || (task = getTask()) != null) {
runTask(task);//执行任务
task = null;
}
} finally {
workerDone(this); //当任务队列中没有任务时,进行清理工作
}
}
}
Runnable getTask() { //从缓存队列中取任务
for (;;) {
try {
int state = runState;
if (state > SHUTDOWN)
return null;
Runnable r;
if (state == SHUTDOWN) // Help drain queue
r = workQueue.poll();
else if (poolSize > corePoolSize || allowCoreThreadTimeOut) //如果线程数大于核心池大小或者允许为核心池线程设置空闲时间,
//则通过poll取任务,若等待一定的时间取不到任务,则返回null
r = workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS);
else
r = workQueue.take();
if (r != null)
return r;
if (workerCanExit()) { //如果没取到任务,即r为null,则判断当前的worker是否可以退出
if (runState >= SHUTDOWN) // Wake up others
interruptIdleWorkers(); //中断处于空闲状态的worker
return null;
}
// Else retry
} catch (InterruptedException ie) {
// On interruption, re-check runState
}
}
}
private boolean workerCanExit() {//判断是否可以退出
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
boolean canExit;
//如果runState大于等于STOP,或者任务缓存队列为空了
//或者 允许为核心池线程设置空闲存活时间并且线程池中的线程数目大于1
try {
canExit = runState >= STOP ||
workQueue.isEmpty() ||
(allowCoreThreadTimeOut &&
poolSize > Math.max(1, corePoolSize));
} finally {
mainLock.unlock();
}
return canExit;
}
void interruptIdleWorkers() {//中断worker
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
for (Worker w : workers) //实际上调用的是worker的interruptIfIdle()方法
w.interruptIfIdle();
} finally {
mainLock.unlock();
}
}
void interruptIfIdle() {
final ReentrantLock runLock = this.runLock;
if (runLock.tryLock()) { //注意这里,是调用tryLock()来获取锁的,因为如果当前worker正在执行任务,锁已经被获取了,是无法获取到锁的
//如果成功获取了锁,说明当前worker处于空闲状态
try {
if (thread != Thread.currentThread())
thread.interrupt();
} finally {
runLock.unlock();
}
}
}