asyntask配合线程池使用

本文探讨了Android开发中AsyncTask线程池的默认配置及其可能导致的问题,特别是线程池爆掉的情况。提供了自定义线程池的实现方案,包括如何设置核心线程数、最大线程数及等待队列等参数,以实现更灵活的任务调度。

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 Build.VERSION_CODES.DONUT, this was changed to a pool of threads allowing multiple tasks to operate in parallel. Starting with Build.VERSION_CODES.HONEYCOMB, tasks are executed on a single thread to avoid common application errors caused by parallel execution.

If you truly want parallel execution, you can invoke executeOnExecutor(java.util.concurrent.Executor,java.lang.Object[]) withTHREAD_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;">
    }

形如上面的代码片,我们自定义了ThreadPoolExecutor,并配置了参数,代码中设置核心线程数为5,最大线程数128,同时自定义了等待队列。同时实现一个get方法方便使用线程池。
  getDetailTask.execute(threadContronler.getPool());
上面的代码asyntask将在自定义线程池中执行。


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值