今天碰到Webveiw初始化时候居然跟AsyncTask的线程池有关,做些整理。
AsyncTask的执行方法有两种execute和executeOnExecutor,前者使用默认线程池,后者要设置线程池,AsyncTask本身提供了两个全局的线程池
SERIAL_EXECUTOR:同步线程池,一次执行一个。
THREAD_POOL_EXECUTOR:异步线程池,一次执行多个。
(1)SERIAL_EXECUTOR的历史:
在2.3.3(level 10)之前,使用的默认线程池是THREAD_POOL_EXECUTOR,当时还没有SERIAL_EXECUTOR。3.0(level 11)之后的默认线程池变成了SERIAL_EXECUTOR。
SERIAL_EXECUTOR。
版本区间 | 1.0~2.3.3 | 2.3.3~now |
默认线程池 | 并发 | 同步 |
(2)THREAD_POOL_EXECUTOR的历史:
4.3之前:CORE_POOL_SIZE=5;MAXIMUM_POOL_SIZE=128;队列数是10
4.3之后:CORE_POOL_SIZE=CPU_COUNT+1;MAXIMUM_POOL_SIZE=CPU_COUNT*2 + 1;队列数是128
google这样处理最大的利用了手机的cup资源。
如果算上AsyncTask的前身UserTask,UserTask的默认线程池配置是
private static final int CORE_POOL_SIZE = 1;
private static final int MAXIMUM_POOL_SIZE = 10;
private static final int KEEP_ALIVE = 10;
private static final BlockingQueue sWorkQueue =
new LinkedBlockingQueue(MAXIMUM_POOL_SIZE);
版本区间 | 1.0~1.4 | 1.5~4.3 | 4.3~now |
corePoolSize | 1 | 5 | cpuCount+1 |
maximumPoolSize | 10 | 128 | cpuCount*2+1 |
workQueueSize | 10 | 10 | 128 |
简单介绍下几个参数:
corePoolSize:核心池大小,默认线程池初始化线程数为0,当有新任务会创建新线程来执行(即使有空闲线程),当线程池中的线程数目达到corePoolSize后,使用空闲线程来执行,如果没有空闲线程则将任务放入缓存队列。
maximumPoolSize:线程池最大线程数,它表示在线程池中最多能创建多少个线程;
workQueueSize:这个是缓存队列的容量,AsyncTask使用LinkedBlockingQueue来实现,如创建时候new LinkedBlockingQueue(128) 128即为缓存队列容量,LinkedBlockingQueue的默认容量是Integer.MAX_VALUE。
注:
线程池初始化不一定是0,如调用prestartAllCoreThreads()或者prestartCoreThread()方法,可以预先创建线程。
private static class SerialExecutor implements Executor {
final ArrayDeque mTasks = new ArrayDeque();
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);
}
}
}
private static class InternalHandler extends Handler {
public InternalHandler() {
super(Looper.getMainLooper());
}
@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]);//如果没有cancel 执行onPostExecute
break;
case MESSAGE_POST_PROGRESS:
result.mTask.onProgressUpdate(result.mData);//更新进度
break;
}
}
}