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串行。