[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l3sAkhcZ-1587131867238)(C:\Users\80261556.ADC\Desktop\线程池.jpg)]
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
//获取当前线程池的状态以及拥有的线程池数目,高位为状态,低位为数目
int c = ctl.get();
if (workerCountOf(c) < corePoolSize) {
//如果当前线程数目小于核心线程数,则创建核心线程,后面的bool类型参数为true,代表创建核心线程
if (addWorker(command, true))
return;
c = ctl.get();
}
//如果当前线程处于running状态,之后往任务队列中插入新的任务
if (isRunning(c) && workQueue.offer(command)) {
//之后重新检查,如果线程池不是running状态,则从队列中删除,并且reject
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);
}
private boolean addWorker(Runnable firstTask, boolean core) {
retry:
for (;;) {
int c = ctl.get();
int rs = runStateOf(c);
// 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;
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 {
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;
}
从execute方法调用开始,代码如下
public final AsyncTask<Params, Progress, Result> execute(Params... params) {
return executeOnExecutor(sDefaultExecutor, params);
}
public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,
Params... params) {
//一个task只能execute一次
if (mStatus != Status.PENDING) {
switch (mStatus) {
case RUNNING:
throw new IllegalStateException("Cannot execute task:"
+ " the task is already running.");
case FINISHED:
throw new IllegalStateException("Cannot execute task:"
+ " the task has already been executed "
+ "(a task can be executed only once)");
}
}
mStatus = Status.RUNNING;
onPreExecute();
mWorker.mParams = params;
//exec = sDefaultExecutor = SerialExecutor
exec.execute(mFuture);
return this;
}
这里值得注意的是sDefaultExecutor这个成员变量的默认值是SerialExecutor,这是负责调度用的线程池。
public static final Executor SERIAL_EXECUTOR = new SerialExecutor();
private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
关于调度的线程池代码比较好理解,主要是将Runnable插入队列,然后通过scheduleNext调用线程池执行队列中的任务,每一次插入对应一次执行。
private static class SerialExecutor implements Executor {
final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
Runnable mActive;
public synchronized void execute(final Runnable r) {
mTasks.offer(new Runnable() {
public void run() {
try {
r.run();
} finally {
scheduleNext();
}
}
});
if (mActive == null) {
scheduleNext();
}
}
protected synchronized void scheduleNext() {
if ((mActive = mTasks.poll()) != null) {
THREAD_POOL_EXECUTOR.execute(mActive);
}
}
}
关于mFuture,我们只需要知道在里面会轮流调用以下几个方法:
doInBackground(mParams)
postResult(result)
onPostExecute(Result result)
这样,一个task就基本走完了流程,但是很多时候我们需要去在UI线程里面更新进度,这样我们需要在doInBackground() 中调用 publishProgress () 。那么这是怎么实现的呢?
private static class InternalHandler extends Handler {
public InternalHandler(Looper looper) {
super(looper);
}
@SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
@Override
public void handleMessage(Message msg) {
AsyncTaskResult<?> result = (AsyncTaskResult<?>) msg.obj;
switch (msg.what) {
case MESSAGE_POST_RESULT:
// There is only one result
result.mTask.finish(result.mData[0]);
break;
case MESSAGE_POST_PROGRESS:
result.mTask.onProgressUpdate(result.mData);
break;
}
}
}
private void finish(Result result) {
if (isCancelled()) {
onCancelled(result);
} else {
onPostExecute(result);
}
mStatus = Status.FINISHED;
}
其核心主要是handler的使用,通过消息传递机制传递MESSAGE_POST_PROGRESS消息,可以在主线程中更新UI控件,同时我们也可以注意到改handler还有一种消息:MESSAGE_POST_RESULT,同时结合上面的代码,我们可以发现在整个task中有三个方法是运行在主线程中的:
//所以我们也可以在这三个方法中更新UI
onCancelled(result);
onPostExecute(result);
onProgressUpdate(result.mData)
综合上述,我们可以发现AsynTask的所有对象是通过共享两个线程池和一个handler来工作的,其职责如下表
具体 | 职责 |
---|---|
SerialExecutor | 任务队列线程池,负责任务调度 |
THREAD_POOL_EXECUTOR | 真正执行任务的线程池 |
InternalHandler | 异步通信,实现工作线程和主线程的通信,并且实现UI更新 |