文章目录
线程池框架结构
Executor和ExecutorService
Executor作为顶层接口,仅仅提供了一个抽象的execute()方法,具体的实现交给了底层。分别有ThreadPoolExecutor、ScheduledThreadPoolExecutor和ForkJoinPool。
ExecutorService接口中定义子类公用的一些抽象方法定义
AbstractExecutorService
AbstractExecutorService实现了ExecutorService的定义的一些接口的实现方式,采用模板方法模式提供了submit()方法的算法骨架,然后由子类调用具体的execute()方法
submit
public Future<?> submit(Runnable task) {
if (task == null) throw new NullPointerException();
RunnableFuture<Void> ftask = newTaskFor(task, null);
execute(ftask);
return ftask;
}
public <T> Future<T> submit(Runnable task, T result) {
if (task == null) throw new NullPointerException();
RunnableFuture<T> ftask = newTaskFor(task, result);
execute(ftask);
return ftask;
}
public <T> Future<T> submit(Callable<T> task) {
if (task == null) throw new NullPointerException();
RunnableFuture<T> ftask = newTaskFor(task);
execute(ftask);
return ftask;
}
ExecutorService类提供了三个submit方法,主要是创建RunnableFuture对象
newTaskFor
protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
return new FutureTask<T>(runnable, value);
}
protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
return new FutureTask<T>(callable);
}
这个方法主要是创建了FutureTask类的实例,然后调用execute方法时,调用的就是FutureTask,具体的见后面executor方法的介绍
ThreadPoolExecutor
ThreadPoolExecutor提供了线程池的基本实现,如上图,它提供了4个不同参数的构造函数,如果用户未自定义就采用默认的参数,因此直接看最基础的构造函数,源码如下。
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;
}
参数解释:
int corePoolSize :核心线程数
int maximumPoolSize :最大线程数
long keepAliveTime :存活时间
TimeUnit unit :存活时间单位
BlockingQueue workQueue :工作队列
ThreadFactory threadFactory :线程工厂
RejectedExecutionHandler handler:拒绝策略
Executors中的默认实现
Java中通过Executors类提供了一些线程池的默认实现,newSingleThreadExecutor、newFixedThreadEcecutor和newCachedThreadPool。
newSingleThreadExecutor
从源码中可以看出,这是提供了一个corePoolSize和maximumPoolSize都为1的线程池,即单线程。
public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory));
}
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
newFixedThreadPool
从源码中可以看出,这是提供了一个统一设置corePoolSize和maximumPoolSize的线程池,即提供了一个固定线程的线程池。
public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory);
}
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
newCachedThreadPool
从源码中可以看出,这是提供了一个corePoolSize为0,maximumPoolSize不限制(理论上)的线程池,且线程的存活时间为60s,与上述两个线程池不一样的是它的工作队列采用了SynchronousQueue。
public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>(),
threadFactory);
}
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
execute
//采用一个AtomicInteger去存储线程池的状态和当前线程池中正在运行的线程的数量
//因为要存储两个变量,Integer是32位,因此将其一分为二,其中高3位用于存储线程池的状态,剩下的29位用于存储正在运行的线程数
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
//可用来标识线程数的最大值,即逻辑上最大的线程数
private static final int CAPACITY = (1 << COUNT_BITS) - 1;
//从ctl中取出线程池状态
private static int runStateOf(int c) { return c & ~CAPACITY; }
//从ctl中取出当前正在运行的线程数量
private static int workerCountOf(int c) { return c & CAPACITY; }
//将线程池和正在运行的线程数量打包为一个整数
private static int ctlOf(int rs, int wc) { return rs | wc; }
//线程池状态
private static final int RUNNING = -1 << COUNT_BITS;
private static final int SHUTDOWN = 0 << COUNT_BITS;
private static final int STOP = 1 << COUNT_BITS;
private static final int TIDYING = 2 << COUNT_BITS;
private static final int TERMINATED = 3 << COUNT_BITS;
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
//返回当前线程池状态和正在运行的线程数量
int c = ctl.get();
//判断当前正在运行的线程数是否小于核心线程数
if (workerCountOf(c) < corePoolSize) {
//如果任务线程成功start()
if (addWorker(command, true))
return;
//再次获得线程池状态和正在运行的线程数量
c = ctl.get();
}
//判断线程池状态是否还在运行并且向工作队列中添加任务
if (isRunning(c) && workQueue.offer(command)) {
//再次检查Ctl
int recheck = ctl.get();
//如果线程池不在运行中,则将任务从队列中移除,并尝试关闭线程池
if (! isRunning(recheck) && remove(command))
//根据拒绝策略拒绝这个任务
reject(command);
//如果正在运行的线程数为零
else if (workerCountOf(recheck) == 0)
//创建一个临时线程去阻塞队列中获取任务来执行。
addWorker(null, false);
}
//如果线程状态不是RUNNING或者向队列中添加任务失败,再次尝试申请线程启动任务
else if (!addWorker(command, false))
//根据拒绝策略拒绝这任务
reject(command);
}
线程池具有以下五种状态,当创建一个线程池时初始化状态为RUNNING
线程池状态 | 描述 |
---|---|
RUNNING | 允许提交并处理任务 |
SHUTDOWN | 不允许提交新的任务,但是会处理完已提交的任务 |
STOP | 不允许提交新的任务,也不会处理阻塞队列中未执行的任务,并设置正在执行的线程的中断标志位 |
TIDYING | 所有任务执行完毕,池中工作的线程数为0,等待执行terminated()勾子方法 |
TERMINATED | terminated()勾子方法执行完毕 |
addWorker
private final HashSet<Worker> workers = new HashSet<Worker>();
//core用来标识使用corePoolSize判断还是maxinumPoolSize
private boolean addWorker(Runnable firstTask, boolean core) {
retry:
for (;;) {
int c = ctl.get();
int rs = runStateOf(c);
// Check if queue empty only if necessary.
// 线程池不是RUNNING状态且
if (rs >= SHUTDOWN &&
//线程池不是SHUTDOWN或者任务非空的或者工作队列是空的
! (rs == SHUTDOWN &&
firstTask == null &&
! workQueue.isEmpty()))
return false;
for (;;) {
int wc = workerCountOf(c);
//如果当前运行的线程数大于或者等于最大线程数
if (wc >= CAPACITY ||
//或者大于指定值
wc >= (core ? corePoolSize : maximumPoolSize))
return false;
//通过CAS操作对正在运行的线程数+1,如果成功跳出循环
if (compareAndIncrementWorkerCount(c))
break retry;
//重新获得线程池状态和正在运行的线程数
c = ctl.get();
//如果线程池状态改变了重新循环
if (runStateOf(c) != rs)
continue retry;
// else CAS failed due to workerCount change; retry inner loop
}
}
boolean workerStarted = false;
boolean workerAdded = false;
Worker w = null;
try {
w = new Worker(firstTask);
final Thread t = w.thread;
if (t != null) {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
// Recheck while holding lock.
// Back out on ThreadFactory failure or if
// shut down before lock acquired.
//再次判断线程池的运行状态
int rs = runStateOf(ctl.get());
if (rs < SHUTDOWN ||
(rs == SHUTDOWN && firstTask == null)) {
// 判断当前线程状态
if (t.isAlive()) // precheck that t is startable
throw new IllegalThreadStateException();
//当任务添加到任务集合中
workers.add(w);
int s = workers.size();
if (s > largestPoolSize)
largestPoolSize = s;
workerAdded = true;
}
} finally {
mainLock.unlock();
}
if (workerAdded) {
// 如果任务成功加入集合,将该任务的线程启动
t.start();
workerStarted = true;
}
}
} finally {
if (! workerStarted)
//任务开启失败
addWorkerFailed(w);
}
return workerStarted;
}
addWorkerFailed
//任务添加集合失败或者任务启动失败
private void addWorkerFailed(Worker w) {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
if (w != null)
//从集合中移除任务
workers.remove(w);
//采用CAS对正在运行的线程数-1
decrementWorkerCount();
tryTerminate();
} finally {
mainLock.unlock();
}
}
tryTerminate
//尝试关闭线程池
final void tryTerminate() {
for (;;) {
int c = ctl.get();
//
if (isRunning(c) ||
runStateAtLeast(c, TIDYING) ||
(runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty()))
return;
if (workerCountOf(c) != 0) { // Eligible to terminate
interruptIdleWorkers(ONLY_ONE);
return;
}
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) {
try {
terminated();
} finally {
ctl.set(ctlOf(TERMINATED, 0));
termination.signalAll();
}
return;
}
} finally {
mainLock.unlock();
}
// else retry on failed CAS
}
}
reject
final void reject(Runnable command) {
handler.rejectedExecution(command, this);
}
拒绝策略
RejectedExceptionHandler | 特性及效果 |
---|---|
AbortPolicy | 线程池默认的策略,如果元素添加到线程池失败,会抛出RejectedExecutionException异常 |
DiscardPolicy | 如果添加失败,则放弃,并且不会抛出任何异常 |
DiscardOldestPolicy | 如果添加失败,会将队列中最早添加的元素移除,再尝试添加,如果失败则按该策略不断重试 |
CallerRunsPolicy | 如果添加失败,那么主线程会自己调用执行器中的execute方法来执行任务 |
Worker
private final class Worker extends AbstractQueuedSynchronizer implements Runnable {
Worker(Runnable firstTask) {
setState(-1); // inhibit interrupts until runWorker
this.firstTask = firstTask;
this.thread = getThreadFactory().newThread(this);
}
/** Delegates main run loop to outer runWorker */
public void run() {
runWorker(this);
}
}
用户提交的任务并不是直接运行了然后封装了一层worker,真正启动的是Worker
runWorker
final void runWorker(Worker w) {
Thread wt = Thread.currentThread();
Runnable task = w.firstTask;
w.firstTask = null;
w.unlock(); // allow interrupts
boolean completedAbruptly = true;
try {
while (task != null || (task = getTask()) != null) {
w.lock();
// If pool is stopping, ensure thread is interrupted;
// if not, ensure thread is not interrupted. This
// requires a recheck in second case to deal with
// shutdownNow race while clearing interrupt
if ((runStateAtLeast(ctl.get(), STOP) ||
(Thread.interrupted() &&
runStateAtLeast(ctl.get(), STOP))) &&
!wt.isInterrupted())
wt.interrupt();
try {
//可以重写该方法完成一些execute之前的操作
beforeExecute(wt, task);
Throwable thrown = null;
try {
task.run();//真正的运行任务,调用run()方法,并未开始异步线程,start()方法才会开启异步线程
} catch (RuntimeException x) {
thrown = x; throw x;
} catch (Error x) {
thrown = x; throw x;
} catch (Throwable x) {
thrown = x; throw new Error(x);
} finally {
//可以重写该方法完成一些execute之后的操作
afterExecute(task, thrown);
}
} finally {
task = null;
w.completedTasks++;
w.unlock();
}
}
completedAbruptly = false;
} finally {
processWorkerExit(w, completedAbruptly);
}
}
getTask
从阻塞队列中获取任务
//是否允许核心线程池超时
private volatile boolean allowCoreThreadTimeOut;
private Runnable getTask() {
boolean timedOut = false; // Did the last poll() time out?
for (;;) {
int c = ctl.get();
int rs = runStateOf(c);
// Check if queue empty only if necessary.
if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
decrementWorkerCount();
return null;
}
int wc = workerCountOf(c);
// 是否允许核心线程池超时,或者当前运行的线程数大于核心线程数
boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
if ((wc > maximumPoolSize || (timed && timedOut))
&& (wc > 1 || workQueue.isEmpty())) {
if (compareAndDecrementWorkerCount(c))
return null;
continue;
}
try {
Runnable r = timed ?
workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
workQueue.take();
if (r != null)
return r;
timedOut = true;
} catch (InterruptedException retry) {
timedOut = false;
}
}
}
FutureTask
在runWorker()方法中可以看到Worker线程去调用了任务的run()方法,对于FutureTask任务来说也是调用了它重写的run()方法。
public void run() {
if (state != NEW ||
!UNSAFE.compareAndSwapObject(this, runnerOffset,
null, Thread.currentThread()))
return;
try {
Callable<V> c = callable;
if (c != null && state == NEW) {
V result;
boolean ran;
try {
result = c.call();
ran = true;
} catch (Throwable ex) {
result = null;
ran = false;
setException(ex);
}
if (ran)
set(result);
}
} finally {
// runner must be non-null until state is settled to
// prevent concurrent calls to run()
runner = null;
// state must be re-read after nulling runner to prevent
// leaked interrupts
int s = state;
if (s >= INTERRUPTING)
handlePossibleCancellationInterrupt(s);
}
}
在run()方法中调用了任务的call()方法,拿到返回结果
ScheduledExecutorsService
ScheduledExecutorsService主要提供了创建定时任务的几种方式
ScheduledThreadPoolExecutor
ScheduledThreadPoolExecutor也是继承了ThreadPoolExecutor,但是在普通线程池的基础上提供了定时任务的功能。从下面的源码看出,它实际上也是调用了ThreadPoolExecutor的构造函数,提供了一个corePoolSize可设置,maximumPoolSize不限制(理论上)的线程池,定时任务的功能主要是通过DelayedWorkQueue队列实现。
public ScheduledThreadPoolExecutor(int corePoolSize,
ThreadFactory threadFactory) {
super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
new DelayedWorkQueue(), threadFactory);
}
Executors中的默认实现
Java中通过Executors类提供了定时任务线程池的默认实现,newScheduledThreadPool。
newScheduledThreadPool
从源码看出并没有额外功能的添加
public static ScheduledExecutorService newScheduledThreadPool(
int corePoolSize, ThreadFactory threadFactory) {
return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
}
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}
ScheduledFutureTask
public void run() {
boolean periodic = isPeriodic();
if (!canRunInCurrentRunState(periodic))
cancel(false);
else if (!periodic)
ScheduledFutureTask.super.run();
else if (ScheduledFutureTask.super.runAndReset()) {
setNextRunTime();
reExecutePeriodic(outerTask);
}
}
与FutureTask一样,ScheduledFutureTask的run执行业务逻辑以后 将重新计算对象的 delay 时间,再通过 runAndReset 方法将重新计算的后的对象重置回工作任务阻塞队列中。由于默认实现的 compareTo 方法,这样,就实现了线程周期性的执行任务的功能。
ForkJoinPool
这是在1.7中新增的一个采用forkjoin模式处理任务的线程池,比较特殊。
public ForkJoinPool(int parallelism,
ForkJoinWorkerThreadFactory factory,
UncaughtExceptionHandler handler,
boolean asyncMode) {
this(checkParallelism(parallelism),
checkFactory(factory),
handler,
asyncMode ? FIFO_QUEUE : LIFO_QUEUE,
"ForkJoinPool-" + nextPoolId() + "-worker-");
checkPermission();
}
newWorkStealingPool
public static ExecutorService newWorkStealingPool() {
return new ForkJoinPool
(Runtime.getRuntime().availableProcessors(),
ForkJoinPool.defaultForkJoinWorkerThreadFactory,
null, true);
}
public static ExecutorService newWorkStealingPool(int parallelism) {
return new ForkJoinPool
(parallelism,
ForkJoinPool.defaultForkJoinWorkerThreadFactory,
null, true);
}
参考链接:fork-join模型介绍