使用多线程,必然要用到线程池,而ThreadPoolExecutor是java中线程池的重要实现类,理解ThreadPoolExecutor有助于我们更好地理解线程池、甚至去自定义自己的线程池。
Executor executor=new ThreadPoolExecutor(0,Integer.MAX_VALUE,60, TimeUnit.MILLISECONDS,new SynchronousQueue());
executor.execute(runnable);
我们先来看一下ThreadPoolExecutor的工作原理图解,不明白不要紧,再继续看完源码分析便会明白了
源码中,我们重点分析构造方法和几个重要的方法,execute、addWorker、runWorker和getTask
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize
long keepAliveTime,
TimeUnit unit,
BlockingQueue workQueue,
RejectedExecutionHandler handler)
public void execute(Runnable command) {
int c = ctl.get();
//1. 运行任务数和核心线程数作比较
// 如果运行任务数少,则新建一个线程作为核心线程,并执行该任务
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
c = ctl.get();
}
//2. 如果一个任务能够放到队列中
// 再次检查,当前线程池状态不是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);
}
//3. 如果能放到线程池中,则作为非核心线程去执行
//4. 否则使用拒绝策略进行拒绝
else if (!addWorker(command, false))
reject(command);
}
private boolean addWorker(Runnable firstTask, boolean core) {
boolean workerStarted = false;
boolean workerAdded = false;
Worker w = null;
try {
//1. 创建Worker和线程
w = new Worker(firstTask);
final Thread t = w.thread;
if (t != null) {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
//2. 将worker添加到集合中
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();
}
//3. 让线程开始执行
if (workerAdded) {
t.start();
workerStarted = true;
}
}
} finally {
if (! workerStarted)
addWorkerFailed(w);
}
return workerStarted;
}
final void runWorker(Worker w) {
Thread wt = Thread.currentThread();
Runnable task = w.firstTask;
w.firstTask = null;
w.unlock(); // allow interrupts
boolean completedAbruptly = true;
try {
//1. 此行为关键代码,循环获取任务并执行
while (task != null || (task = getTask()) != null) {
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;
w.completedTasks++;
w.unlock();
}
}
completedAbruptly = false;
} finally {
//处理worker退出
processWorkerExit(w, completedAbruptly);
}
}
private Runnable getTask() {
//标记是否超时
boolean timedOut = false; // Did the last poll() time out?
//无限循环从队列中获取任务,无任务时线程会阻塞等待任务,不消耗CPU资源
for (;;) {
int c = ctl.get();
int rs = runStateOf(c);
//1. 检查一:线程终止且队列为空,直接返回null
if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
decrementWorkerCount();
return null;
}
int wc = workerCountOf(c);
//标记线程是否可以超时停止
boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
//2. 检查二:工作线程数目以及是否超时
if ((wc > maximumPoolSize || (timed && timedOut))
&& (wc > 1 || workQueue.isEmpty())) {
if (compareAndDecrementWorkerCount(c))
return null;
continue;
}
//3. 从队列中取出任务并返回
try {
//poll方法:从BlockingQueue取出一个队首的对象,如果在指定时间内,
队列一旦有数据可取,则立即返回队列中的数据。否则知道时间超时还没有数据可取,返回null
Runnable r = timed ?
workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
workQueue.take();
if (r != null)
return r;
timedOut = true;
} catch (InterruptedException retry) {
timedOut = false;
}
}
}