AsyncTask裏面封裝了線程池和Handler,所以很是方便我們使用它來處理ui線程和工作線程之間的異步任務的邏輯工作。
AsyncTask裏面的的線程池的實現是用ThreadPoolExecutor來實現的。然而ThreadPoolExecutor的的執行邏輯在cpu多核情況下,執行順序是不確定的,也就是並行的。
AsyncTask裏面有兩個線程池的靜態常量 這就保證了整個邏輯內只有一個線程池。
- THREAD_POOL_EXECUTOR 多核下,並行,單核下串行。
- SERIAL_EXECUTOR,單核和多核下都是串行。
下面是THREAD_POOL_EXECUTOR的實現和定義。
/**
* An {@link Executor} 並行執行的線程池.
*/
public static final Executor THREAD_POOL_EXECUTOR;
static {
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS, TimeUnit.SECONDS,
sPoolWorkQueue, sThreadFactory, new ThreadPoolExecutor.DiscardOldestPolicy());
threadPoolExecutor.allowCoreThreadTimeOut(true);
THREAD_POOL_EXECUTOR = threadPoolExecutor;
}
下面是SERIAL_EXECUTOR的實現。SERIAL_EXECUTOR的實現是基於THREAD_POOL_EXECUTOR,但加入了串行邏輯。具體的實現邏輯全在scheduleNext這個方法裏面。如下。
private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR;
/**
* 一個{@link Executor},按串行順序一次執行一個任務。這種序列化對於特定的流程是全局的。
*/
public static final Executor SERIAL_EXECUTOR = new SerialExecutor();
/**
* 串行Executor,基於THREAD_POOL_EXECUTOR實現串行
*/
private static class SerialExecutor implements Executor {
/**
* 串行任務的雙端隊列
*/
final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
Runnable mActive;
@Override
public synchronized void execute(final Runnable r) {
mTasks.offer(new Runnable() {
@Override
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);
}
}
}
AsyncTask提供了幾個執行方法。
1,串行。AsyncTask提供了靜態方法execute,直接傳入Runnable對象,進行串行執行,注意該方法需要在UI線程中調用。
AsyncTask.execute(new Runnable() {
@Override
public void run() {
//異步邏輯
}
});
看一下靜態方法execute的源碼,使用的是默認的sDefaultExecutor執行的。
@MainThread
public static void execute(Runnable runnable) {
sDefaultExecutor.execute(runnable);
}
默認情況下,sDefaultExecutor的默認值是SERIAL_EXECUTOR。而SERIAL_EXECUTOR是實現是AsyncTask的靜態內部類SerialExecutor。SerialExecutor的實現是串行的。所以,默認情況下sDefaultExecutor的行爲是串行的。
2,串行,AsyncTask還提供了一個execute成員方法。裏面調用的executeOnExecutor成員方法傳入的是sDefaultExecutor線程池,
@MainThread
public final AsyncTask<Params, Progress, Result> execute(Params... params) {
return executeOnExecutor(sDefaultExecutor, params);
}
再看executeOnExecutor方法。
@MainThread
public final MyAsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,
Params... params) {
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.execute(mFuture);
return this;
}
3,串行,並行隨你選。
executeOnExecutor方法支持你指定線程池。傳入THREAD_POOL_EXECUTOR並行,傳入SERIAL_EXECUTOR串行。