文章目录
学习
ThreadPoolExecutor
源码
版本:JDK 8
一、构造方法
如图:
(1)corePoolSize
核心线程数
-
若
corePoolSize == 0
,则任务执行完之后,没有任何请求进入时,销毁线程池的线程 -
若
corePoolSize > 0
,即使本地任务执行完毕,核心线程也不会被销毁
(2)maximumPoolSize
表示线程池能够容纳同时执行的最大线程数
-
maximumPoolSize >= 1
必须大于等于 1 -
maximumPoolSize == corePoolSize
,即是固定大小线程池 -
待执行的线程数 >
maximumPoolSize
,则交付给缓存队列
(3)keepAliveTime
线程空闲时间
-
当空闲时间达到
keepAliveTime
值时,线程会被销毁,直到只剩下corePoolSize
个线程为止,避免浪费内存和句柄资源 -
默认情况,当线程池的线程数 >
corePoolSize
时,keepAliveTime
才会起作用 -
但当
ThreadPoolExecutor
的allowCoreThreadTimeOut
变量设置为 true 时,核心线程超时后会被回收
(4)workQueue
缓存队列
当请求的线程数 > maximumPoolSize
时,线程进入BlockingQueue
阻塞队列
(5)threadFactory
线程工厂
用来生产一组相同任务的线程
(6)handler
执行拒绝策略的对象
限流保护。
友好的拒绝策略:
(1)保存到数据库进行削峰填谷。在空闲时再提取出来执行。
(2)转向某个提示页面
(3)打印日志
二、属性定义
如图:
线程池的状态用 高3位表示,其中包括了符号位。
五种状态的十进制排序:RUNNING < SHUTDOWN < STOP < TIDYING < TERMINATED
三、方法
(1)execute()
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
// 返回包含线程数及线程池状态(头3位)
int c = ctl.get();
// 如果工作线程数小于核心线程数,则创建线程任务执行
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
// 如果创建失败,防止外部已经在线程池中加入新任务,重新获取
c = ctl.get();
}
// 只有线程池处于 RUNNING 状态,且 入队列成功
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
// 如果线程池不是 RUNNING 状态,则将刚加入队列的任务移除
if (! isRunning(recheck) && remove(command))
reject(command);
// 如果之前的线程已被消费完,新建一个线程
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
// 核心池和队列都满了,尝试创建一个新线程
else if (!addWorker(command, false))
// 如果 addWorker 返回是 false,即创建失败,则唤醒拒绝策略
reject(command);
}
(2)addWorker()
private boolean addWorker(Runnable firstTask, boolean core) {
// 用于快速退出多层嵌套循环
retry:
for (;;) {
int c = ctl.get();
int rs = runStateOf(c);
// Check if queue empty only if necessary.
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;
// 将当前线程数 + 1
if (compareAndIncrementWorkerCount(c))
break retry;
c = ctl.get(); // Re-read ctl
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;
}
四、内部类
(1)Worker
对象
private final class Worker
extends AbstractQueuedSynchronizer
implements Runnable
{
private static final long serialVersionUID = 6138294804551838833L;
final Thread thread;
Runnable firstTask;
volatile long completedTasks;
Worker(Runnable firstTask) {
setState(-1); // inhibit interrupts until runWorker
this.firstTask = firstTask;
this.thread = getThreadFactory().newThread(this);
}
public void run() {
runWorker(this);
}
// Lock methods
//
// The value 0 represents the unlocked state.
// The value 1 represents the locked state.
protected boolean isHeldExclusively() {
return getState() != 0;
}
protected boolean tryAcquire(int unused) {
if (compareAndSetState(0, 1)) {
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
return false;
}
protected boolean tryRelease(int unused) {
setExclusiveOwnerThread(null);
setState(0);
return true;
}
public void lock() { acquire(1); }
public boolean tryLock() { return tryAcquire(1); }
public void unlock() { release(1); }
public boolean isLocked() { return isHeldExclusively(); }
void interruptIfStarted() {
Thread t;
if (getState() >= 0 && (t = thread) != null && !t.isInterrupted()) {
try {
t.interrupt();
} catch (SecurityException ignore) {
}
}
}
}
(2)其他静态内部类
-
AbortPolicy(默认)
: 丢弃任务并抛出RejectExecutionException
异常 -
DiscardPolicy
:丢弃任务,但是不抛出异常,这是不推荐的做法 -
DiscardOldestPolicy
:抛弃队列中等待最久的任务,然后把当前任务加入队列中 -
CallerRunsPolicy
: 调用任务的run()
方法绕过线程池直接执行