今天碰到Webveiw初始化时候居然跟AsyncTask的线程池有关,做些整理。
1.线程池的历史。
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<Runnable> sWorkQueue =
new LinkedBlockingQueue<Runnable>(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()方法,可以预先创建线程。
2.线程数量和任务的控制
默认情况:keepAliveTime看单词的意思就知道,是线程的存活时间,线程大于corePoolSize时,多出来的线程执行任务完毕后,等待keepAliveTime时间后,进入死亡状 态,直到线程池中的线程数不大于corePoolSize,如果:调用allowCoreThreadTimeOut(true)方法,keepAliveTime起作用,直到线程池中的线程数为0;
keepAliveTime的时间单位有7种取值,在TimeUnit类中有7种静态属性:
TimeUnit.DAYS; //天
TimeUnit.HOURS; //小时
TimeUnit.MINUTES; //分钟
TimeUnit.SECONDS; //秒
TimeUnit.MILLISECONDS; //毫秒
TimeUnit.MICROSECONDS; //微妙
TimeUnit.NANOSECONDS; //纳秒
ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。
ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务
3.SERIAL_EXECUTOR的实现
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);
}
}
}
4.AsyncTask与Handler的关系
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;
}
}
}