线程池
线程池状态由32位二,进制组成,前三位为线程池状态后29位为现场数量
private static final int COUNT_BITS = Integer.SIZE - 3;计数位为 32 -3 = 29 现场数量对应
容量
private static final int CAPACITY = (1 << COUNT_BITS) - 1; 意为000111… 29个1
线程池状态正在运行
private static final int RUNNING = -1 << COUNT_BITS; -1 左移29位为 111
即将关闭 不接受新任务但是存在的任务继续运行 调用线程池shutdown()方法
private static final int SHUTDOWN = 0 << COUNT_BITS; 0 左移 29 0
停止 不在处理任务 中断所有任务 调用 shutdownNow()方法
private static final int STOP = 1 << COUNT_BITS; 1左移29位 001 000... 29个0
当所有的任务已终止,记录的”任务数量”为0,线程池会变为TIDYING状态。当线程池变为TIDYING状态时,会执行钩子函数terminated()。
private static final int TIDYING = 2 << COUNT_BITS; -> 010 000... 29个0
当钩子函数terminated()被执行完成之后,线程池彻底终止,就变成TERMINATED状态。
private static final int TERMINATED = 3 << COUNT_BITS; 011 000... 29个0
// Packing and unpacking ctl
与运算计算快
获取当前线程状态
private static int runStateOf(int c) { return c & ~CAPACITY; }
获取当前线程数量
private static int workerCountOf(int c) { return c & CAPACITY; }
初始化线程数量调用
private static int ctlOf(int rs, int wc) { return rs | wc; }
主要执行方法
public void execute(Runnable command)
-
private boolean addWorker(Runnable firstTask, boolean core) {
//未有结果继续执行
retry:
for (;😉 {
//获取当前线程值
int c = ctl.get();
//线程状态
int rs = runStateOf©;// 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 { //包装我们提交的任务质量交给worker w = new Worker(firstTask); final Thread t = w.thread; //worker详解 将客户的runnabel任务包装到woker里,委托给work执行 其中任务可以为空,如为空则去队列中去取,保证线程可持续运用的前提 ***线程复用的依靠worker中的 while循环一直在寻找任务 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;
}
Worker 实际线程执行者,且循环找任务执行
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 {
beforeExecute(wt, task);
Throwable thrown = null;
try {
task.run();
} catch (RuntimeException x) {
thrown = x; throw x;
} catch (Error x) {
thrown = x; throw x;
} catch (Throwable x) {
thrown = x; throw new Error(x);
} finally {
afterExecute(task, thrown);
}
} finally {
task = null;
w.completedTasks++;
w.unlock();
}
}
completedAbruptly = false;
} finally {
processWorkerExit(w, completedAbruptly);
}
}
如果核心线程数量满了则加入到阻塞队列中,阻塞队列满了则按最大线程数创建线程执行,如果最大线程数也满了。则执行拒绝策略 线程池默认四种拒绝策略
1.直接由本身线程执行
2.直接拒绝不作为
3.抛出老的任务加入新的任务
4.直接抛出异常
阻塞队列原理
内部存在一个ReentrantLock —
/** Condition for waiting takes */
不是空
private final Condition notEmpty;
不是满
private final Condition notFull;
采用sign 和 await 互相锁定标记唤醒
如加入一个任务 则唤醒非空等待 notEmpty.sign(),
没有则锁定 notEmpty.await()
%%% 注意唤醒等待未知应为while循环处理,否则产生虚假唤醒,导致出现垃圾问题凉凉
ScheduleThreadPool为什么可以周期性执行
public ScheduledFuture<?> schedule(Runnable command,
long delay,
TimeUnit unit) {
if (command == null || unit == null)
throw new NullPointerException();
//装饰者模式增强callable
RunnableScheduledFuture<?> t = decorateTask(command,
new ScheduledFutureTask<Void>(command, null,
triggerTime(delay, unit)));
delayedExecute(t);
return t;
}
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);
}
}
此处重新先队列增加task已达到循环调用
void reExecutePeriodic(RunnableScheduledFuture<?> task) {
if (canRunInCurrentRunState(true)) {
super.getQueue().add(task);
if (!canRunInCurrentRunState(true) && remove(task))
task.cancel(false);
else
ensurePrestart();
}
}