asynctask遇到的问题
在android开发中许多同学都可能遇到asynctask的线程池爆掉的情况。
private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
181 private static final int CORE_POOL_SIZE = CPU_COUNT + 1;
182 private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
183 private static final int KEEP_ALIVE = 1;
192
193 private static final BlockingQueue<Runnable> sPoolWorkQueue =
194 new LinkedBlockingQueue<Runnable>(128);
上面的代码片中可以看出。
1、asynctask的核心线程数为CPU_COUNT+1。
2、线程等待队列的最大等待数为128。
asyntask对应的线城池ThreadPoolExecutor都是进程范围内共享的,其都是static的,所以是AsyncTask控制着进程范围内所有的子类实例。由于这个限制的存在,当使用默认线程池时,如果线程数超过线程池的最大容量,线程池就会爆掉。针对这种情况,可以尝试自定义线程池,配合asyntask使用。
asynctask自定义线程池
当我们在某个activity中开启多个线程池,用一个独立的线程池就显得比较方便,当然独立的线程池也需要一定的开销。独立线程池的会带来好处:
1、管理页面的线程,使其与activity联动:
在Activity中,当页面的生命周期结束时,asynctask中的异步任务可能还没有完成,这导致了潜在的不稳定。一般情况下我们会做如下的处理:
if (activity == null || activity.isDestroy()) {//避免activity已经结束造成的空指针
return;
}
在独立线程池中,我们通过终止线程池中的线程并销毁线程池的方式避免了上述情况的出现。同样的我们也可以实现一组形如onstart(),onpause()的方法来使线程池的生命周期和activity的生命周期联动。 由于独立线程池的存在,我们可以在页面不需要时彻底的销毁这个线程池并关闭所有的线程,这样可以有效的避免部分僵尸线程的存在。2、自定义线程池的想关参数
下面的内容可以看出系统默认线程池的策略。
When first introduced, AsyncTasks were executed serially on a single background thread. Starting with
, this was changed to a pool of threads allowing multiple tasks to operate in parallel. Starting with Build.VERSION_CODES.DONUT
, tasks are executed on a single thread to avoid common application errors caused by parallel execution.Build.VERSION_CODES.HONEYCOMB
If you truly want parallel execution, you can invoke
withexecuteOnExecutor(java.util.concurrent.Executor,java.lang.Object[])
.THREAD_POOL_EXECUTOR
默认线程存在这着线程池大小的限制,形如核心线程数限制为CPU_COUNT+1,这意味着同时并发执行的线程数为CPU_COUNT+1。自定义线程池均可设置这些参数,使用自定义的CorePoolSize为7的Executor(Executors.newFixedThreadPool(7)),这样可以同时并发执行7个异步线程,超过7个时则需等待。
asynctask自定义线程池实现
private static final int CORE_POOL_SIZE = 5;
private static final int MAXIMUM_POOL_SIZE = 128;
private static final int KEEP_ALIVE = 1;
private ThreadFactory sThreadFactory = new ThreadFactory() {
private final AtomicInteger mCount = new AtomicInteger(1);
public Thread newThread(Runnable r) {
return new Thread(r, "AsyncTask #" + mCount.getAndIncrement());
}
};
private BlockingQueue<Runnable> sPoolWorkQueue = new LinkedBlockingQueue<Runnable>(10);
/**
* An {@link Executor} that can be used to execute tasks in parallel.
*/
public ThreadPoolExecutor threadPool= new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);
public ThreadPoolExecutor getPool(){
return </span><span style="font-size: 14px;">threadpool</span><span style="font-family: Arial, Helvetica, sans-serif;">;</span><span style="font-size:14px;">
}
getDetailTask.execute(threadContronler.getPool());
上面的代码asyntask将在自定义线程池中执行。