查看线程死锁命令
jstack [进程id]
线程池的7个参数
public ThreadPoolExecutor(int corePoolSize, //核心线程数
int maximumPoolSize, //最大线程数
long keepAliveTime, //最大线程空闲时间
TimeUnit unit, //时间单位
BlockingQueue<Runnable> workQueue, //工作队列
ThreadFactory threadFactory, //线程工厂
RejectedExecutionHandler handler //拒绝策略(四个)
){}
如果核心线程没有空闲(满了),会将新创建的线程放进阻塞队列中,如果前两个都满了,新建的线程就会放在最大线程数里。
最大线程空闲时间
线程工厂:定义线程名,如果线程报错可以查看哪个线程报错。
线程池的核心属性
//本质是一个int类型的数值,前三位标识线程的状态,后二十九位标识线程的数量
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
//本质就是29,为了方便对ctl做位运算使用的常量
private static final int COUNT_BITS = Integer.SIZE - 3;
//计算出当前线程池的线程最大容量
private static final int CAPACITY = (1 << COUNT_BITS) - 1;
// 线程池正常运行 标识 :111
private static final int RUNNING = -1 << COUNT_BITS;
//线程池被shutdown,继续执行完剩下的任务 标识:000
private static final int SHUTDOWN = 0 << COUNT_BITS;
//线程池被shutdownNow,线程池停止,不会执行剩下的任务 标识:001
private static final int STOP = 1 << COUNT_BITS;
//shutdown和shutdownNow,任务都被处理完成之后,到这个过渡状体 标识: 010
private static final int TIDYING = 2 << COUNT_BITS;
//线程池停止 标识;011
private static final int TERMINATED = 3 << COUNT_BITS;
线程池核心的execute方法流程
public void execute(Runnable command) {
//健壮性判断,避免传入为null的任务
if (command == null)
throw new NullPointerException();
// 获取ctl
int c = ctl.get();
// 基于workerCountOf获取正在工作的线程数,判断是否小于核心线程数
if (workerCountOf(c) < corePoolSize) {
//创建核心线程,并且执行任务,传入true表示当前为核心线程
if (addWorker(command, true))
return;
//如果创建核心线程失败,重新获取ctl
c = ctl.get();
}
//isRunning 方法获取线程池状态 workQueue.offer 如果线程池正在running,将任务追加到阻塞队列
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
if (! isRunning(recheck) && remove(command))
reject(command);
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
//尝试创建最大线程数。成功返回true,失败返回false
else if (!addWorker(command, false))
//创建最大线程数失败,创建拒绝策略
reject(command);
}
查看addWorker添加线程操作
private boolean addWorker(Runnable firstTask, boolean core) {
//追加标记
retry:
for (;;) {
//获取ctl
int c = ctl.get();
//获取当前线程池的工作状态
int rs = runStateOf(c);
//如果rs 大于SHUTDOWN,说明线程池执行了shutdown方法或者shutdownNow
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;
//基于CAS的方式,将线程数+1
if (compareAndIncrementWorkerCount(c))
break retry;
//下面就要判断是重新执行内部循环,还是重新执行外部循环
//如果线程池状态改变了,重新执行外部循环
//如果线程池状态没有改变,重新执行内部循环
c = ctl.get(); // Re-read ctl 重新获取ctl
if (runStateOf(c) != rs)
continue retry;
// else CAS failed due to workerCount change; retry inner loop
}
}
//声明了两个标识
boolean workerStarted = false;
boolean workerAdded = false;
//真正的工作线程就是woker
Worker w = null;
try {
//通过new的方式构建,将任务传入
w = new Worker(firstTask);
//woker中有一个thread对象
final Thread t = w.thread;
if (t != null) {
//获取了线程池的全局锁
final ReentrantLock mainLock = this.mainLock;
//上锁,shutdown 或者 shutdownNow的时候,也要获取锁资源
//保证在追加线程的时候,线程池不能被停止
mainLock.lock();
try {
//获取当前线程池的状态
int rs = runStateOf(ctl.get());
// 线程池状态小于SHUTDOWN,也就是判断线程池是否是running状态
if (rs < SHUTDOWN ||
(rs == SHUTDOWN && firstTask == null)) { //线程池为shutdown,任务必须是null
//如果线程干活了,直接抛出异常
//线程还没有追加到线程池,就开始干活了(还没到工作地点就开始干活,老板肯定不愿意)
if (t.isAlive())
throw new IllegalThreadStateException();
//将工作线程追加到HashSet中存储
workers.add(w);
//获取HashSet长度
int s = workers.size();
//如果现在的工作线程个数大于历史最大值,替换掉largestPoolSize
if (s > largestPoolSize)
largestPoolSize = s;
//将工作线程的表示设置为true
workerAdded = true;
}
} finally {
//释放锁
mainLock.unlock();
}
//添加工作线程成功
if (workerAdded) {
//启动任务
t.start();
//设置启动工作线程的表示为true
workerStarted = true;
}
}
} finally {
//如果工作线程启动失败
if (! workerStarted)
//补救操作
addWorkerFailed(w);
}
//返回工作线程是否启动
return workerStarted;
}
查看worker对象
private final class Worker
extends AbstractQueuedSynchronizer
implements Runnable{ //当前worker也就是一个任务
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);
}
//当调用worker内部线程的start()方法时,实际就是调用Worker类中的run方法
//实际执行的就是runWorker()方法
public void run() {
runWorker(this);
}
}
runWorker方法
final void runWorker(Worker w) {
// 获取当前线程
Thread wt = Thread.currentThread();
// 获取Worker中具体的任务
Runnable task = w.firstTask;
// 将Worker中的任务置为null
w.firstTask = null;
// 将有参构造中的标记撤销,代表当前线程可以被打断
w.unlock();
// 标记 值为true
boolean completedAbruptly = true;
try {
//如果Worker中的task有任务,直接执行当前任务,否则去队列中获取任务 getTask()
while (task != null || (task = getTask()) != null) {
//加锁,当前任务要执行,添加标记,shutdown也不会打断
w.lock();
//判断当前线程池状态,以及线程状态,判断是否需要被打断
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,代表任务处理完毕
task = null;
// 标记,当前Woker处理的任务数 +1
w.completedTasks++;
// 释放锁 去掉标记
w.unlock();
}
}
completedAbruptly = false;
} finally {
processWorkerExit(w, completedAbruptly);
}
}