1.原因
创建线程与销毁线程需要消耗资源,
2.目的
保活线程,提高系统的性能
3.线程池包含任务队列与线程池子
1)任务队列获取任务
2)没有任务时阻塞
3)queueSize和core线程数(执行任务的线程数,也就是初始化线程数)、max线程数,当超core线程数并且queueSize达到了最大值,且线程数没有超过max,那么启动新的线程
4)keepalive时间,超出core线程数的数量,设置存活时间,超出这个时间之后,回收线程,节约资源。这么设计原因?为了防止流量突然上涨
5) 任务队列是多线程竞争的是不是需要同步?
java中同步队列是BlockingQueue接口
6)当队列满了且达到了MAX线程数的大小如何处理?
RejectHandler接口,默认抛出RejectException
4.Future接口
1)需要查看任务是否执行完毕或者抛出异常
2)需要等待任务执行完成
runnable 没有返回值,不能抛出异常,callable则可以
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
// c = -536870911(状态位)
int c = ctl.get();
// 工作线程数量小于核心线程池设定数,则创建线程。
if (workerCountOf(c) < corePoolSize) {
// 如果添加成功则直接返回
if (addWorker(command, true))
return;
// 否则再次获取活动线程数量
c = ctl.get();
}
// 如果线程池正在运行,并且添加进队列成功
if (isRunning(c) && workQueue.offer(command)) {
// 再次对线程池状态检查, 因为上面 addWorker 过了并且失败了,所以需要检查
int recheck = ctl.get();
// 如果状态不是运行状态,且从队列删除该任务成功并尝试停止线程池
if (! isRunning(recheck) && remove(command))
// 拒绝任务
reject(command);
// 如果当前工作线程数量为0(线程池已关闭),则添加一个 null 到队列中
else if (workerCountOf(recheck) == 0)
// 添加个空的任务
addWorker(null, false);
}
// 如果添加队列失败,则创建一个任务线程,如果失败,则拒绝
else if (!addWorker(command, false))
// 拒绝
reject(command);
}
}
addwork 创建线程 , workQueue.offer(command) 添加队列(将任务添加到阻塞队列中)
如果正在工作的的线程小于设置的核心线程,则创建线程,如过正在工作的线程大于核心线程数,则试图放入任务的队列,如果失败,则尝创建一个maxnumpoolSize的任务,注意:在remove方法中,该方法已经试图停止线程池的运行
1) addWorker方法 - 创建线程池
private boolean addWorker(Runnable firstTask, boolean core)
第一个参数为Runnable 类型,代表线程池中的某个线程的第一个任务,第二个参数如果是true,则创建核心线程,如果是false,则创建maxnumPoolSize 线程,这两个线程的生命周期是不同的。
2) Worker.runWorker(Worker w) 方法——-线程池的最核心方法
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);
}
}
首先执行firstTask的run方法,然后循环获取阻塞队列中的任务,并且调用他们的run方法,如果线程池中的任务异常,则抛出异常并停止运行线程池。
初始化的核心线程数是直接调用start方法启动线程的,启动之后,这个线程不关闭,而是在阻塞队列上等待,如果有任务就会执行任务的run方法,而不是start方法