android源码、开源框架解析

AsyncTask的原理及优缺点解析

2017-06-08  本文已影响794人  Simon_Zhang

AsyncTask基本使用懂android的都会,但还是有必要整理一下AsyncTask的实现原理,一方面是巩固学习到的知识,另一方面也是为了更深层次的理解AsyncTask的实现。因为我在以前使用AsyncTask 过程的时候一知半解,造成一些代码的问
题。

http://blog.csdn.net/lmj623565791/article/details/38614699
看过hongyang的分析AsyncTask的实现原理的这篇博客,我明白了3.0以前AsyncTask是支持多个线程同步执行任务的,但是3.0及3.0以后AsyncTask实际上是单线程执行的。 也就是说3.0以后我们使用不同的AsyncTask实例去执行任务,还是需要等待之前的任务执行结束,后续任务才能执行

但是还是有个疑惑,为什么之前AsyncTask使用配置的线程池执行任务,最多同时执行128个任务,并等待10个, 并且超过限制会报异常呢?
来看看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 static final ThreadFactory sThreadFactory = new ThreadFactory() {  
private final AtomicInteger mCount = new AtomicInteger(1);  
public Thread newThread(Runnable r) {  
     return new Thread(r, "AsyncTask #" + mCount.getAndIncrement());  
    }  
 };  
private static final BlockingQueue<Runnable> sPoolWorkQueue =  
            new LinkedBlockingQueue<Runnable>(10);  
public static final Executor THREAD_POOL_EXECUTOR  
          =new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,  
                    TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);

http://zhangfengzhe.blog.51cto.com/8855103/1881644
这部分其实是线程配置方面的知识,我们在java中构建自定义线程池时,需要用到ThreadPoolExecutor的构造方法。如下所示:

 public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory,
                          RejectedExecutionHandler handler) {
   
}

参数说明如下:
corePoolSize:核心线程数
maximumPoolSize:最大线程数
keepAliveTime + unit:线程回收时间
workQueue:任务较多时暂存到队列
threadFactory:执行程序创建新线程时使用的工厂
handler:超出线程池容量以及队列长度后拒绝任务的策略

从AsyncTask的构建线程池的代码中可以看出,其中构建的是一个corePoolSize为5,maximumPoolSize为128,任务队列为无界队列LinkedBlockingQueue,队列容纳个数为10. 根据线程池处理流程图:

微信截图_20170608163554.png

我们可以知道,开始可以并行执行5个任务,当任务个数超过corePoolSize核心数时,就会添加到任务队列中,当超过10个的时候就会一直构建新线程去执行任务,一直到线程数量达到128个(线程池的最大数量)。 所以在3.0以前, AsyncTask最多可以同时执行128个任务,同时队列中可以有10个在等待。 如果超过这个数字,就会报RejectedExcpction的异常(超出线程池容量以及队列长度后拒绝任务的策略)。

另1:构建线程池的时候可以使用队列,其中无界队列LinkedBlockingQueue,可以在构建时指定队列容量。

另2:我在使用ScheduledThreadPoolExecutor线程池的时候遇到了 RejectedExcpction异常,我想ScheduledThreadPoolExecutor使用的线程池的队列是无界的,怎么会导致出现这个问题。 后来看到文档说明,如果在执行任务的时候线程池已经“shutdown" 就会拒绝执行。 所以使用线程池执行任务的时候,需要先判断线程池是否已经shutdown();

上一篇 下一篇

猜你喜欢

热点阅读