ThreadPoolExecutor 在 submit或者excute一个线程任务后,是轮训blockqueue获取线程任务来执行还是直接创建线程执行呢,如果是直接创建线程执行,实现的细节是怎么样的呢?
public Future<?> submit(Runnable task) {
if (task == null) throw new NullPointerException();
RunnableFuture<Void> ftask = newTaskFor(task, null);
execute(ftask);
return ftask;
}
可以看出submit也是调用execute函数来执行提交。submit在ThreadPoolExecutor的父类AbstractExecutorService中实现,execute在ThreadPoolExecutor中实现。
int c = ctl.get();
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
c = ctl.get();
}
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);
}
else if (!addWorker(command, false))
reject(command);
execute函数获取当前创建的线程数,如果小于corePoolSize,就新建线程并执行当前的线程任务(private boolean addWorker(Runnable firstTask, boolean core) 来创建并启动一个线程),
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;
addWorker 在做完一系列检查后,通过w = new Worker(firstTask);来创建一个线程,传入的参数firstTask就是submit提交的要执行的线程任务。Worker类是一个实现了Runable接口的类 ,并包含final Thread thread; 成员变量 (private final class Worker extends AbstractQueuedSynchronizer implements Runnable),Worker 类中的成员变量thread创建并初始化的时候传入Worker对象自身实例,
Worker(Runnable firstTask) {
setState(-1); // inhibit interrupts until runWorker
this.firstTask = firstTask;
this.thread = getThreadFactory().newThread(this);
}
最后调用 t.start();执行Worker类的对象中的run函数。实际是执行runwork函数。
public void run() {
runWorker(this);
}
runWorker函数在Worker类的对象firstTask变量不是空的时候就会执行firstTask变量对应的线程任务,否则就去workqueue中取任务,在当前线程中单线程的执行。runWorker是个无限循环,firstTask不为空时先执行firstTask,否则取队列里取任务执行。
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();
getTask()函数所访问的queue就是创建线程池时指定的queue,private final BlockingQueue<Runnable> workQueue;
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
workqueue可以使用如下几种队列:
ArrayBlockingQueue:
有界队列,基于数组结构,按照队列FIFO原则对元素排序;
LinkedBlockingQueue:
无界队列,基于链表结构,按照队列FIFO原则对元素排序,Executors.newFixedThreadPool()使用了这个队列;
SynchronousQueue:
同步队列,该队列不存储元素,每个插入操作必须等待另一个线程调用移除操作,否则插入操作会一直被阻塞,Executors.newCachedThreadPool()使用了这个队列;
PriorityBlockingQueue:
优先级队列,具有优先级的无限阻塞队列。
threadpool拒绝策略:
拒绝策略(RejectedExecutionHandler)也称饱和策略,当线程数量和队列都达到饱和时,就采用饱和策略来处理新提交过来的任务
AbortPolicy:丢弃新任务,并抛出 RejectedExecutionException
DiscardPolicy:不做任何操作,直接丢弃新任务
DiscardOldestPolicy:丢弃队列队首(最老)的元素,并执行新任务
CallerRunsPolicy:由当前调用线程来执行新任务
ThreadPoolExecutor动态设置corePoolSize大小,
调用setCorePoolSize(int size)当调整的参数变小的时候多余的线程就会不会被回收掉。