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);}}}

可以看到,SerialExecutor是使用ArrayDeque这个队列来管理Runnable对象的,如果我们一次性启动了很多个任务,首先在第一次运行execute()方法的时候,会调用ArrayDeque的offer()方法将传入的Runnable对象添加到队列的尾部,然后判断mActive对象是不是等于null,第一次运行当然是等于null了,于是会调用scheduleNext()方法。在这个方法中会从队列的头部取值,并赋值给mActive对象,然后调用THREAD_POOL_EXECUTOR去执行取出的取出的Runnable对象。之后如何又有新的任务被执行,同样还会调用offer()方法将传入的Runnable添加到队列的尾部,但是再去给mActive对象做非空检查的时候就会发现mActive对象已经不再是null了,于是就不会再调用scheduleNext()方法。

那么后面添加的任务岂不是永远得不到处理了?当然不是,看一看offer()方法里传入的Runnable匿名类,这里使用了一个try finally代码块,并在finally中调用了scheduleNext()方法,保证无论发生什么情况,这个方法都会被调用。也就是说,每次当一个任务执行完毕后,下一个任务才会得到执行,SerialExecutor模仿的是单一线程池的效果,如果我们快速地启动了很多任务,同一时刻只会有一个线程正在执行,其余的均处于等待状态。Android照片墙应用实现,再多的图片也不怕崩溃这篇文章中例子的运行结果也证实了这个结论。

不过你可能还不知道,在Android 3.0之前是并没有SerialExecutor这个类的,那个时候是直接在AsyncTask中构建了一个sExecutor常量,并对线程池总大小,同一时刻能够运行的线程数做了规定,代码如下所示:

private static final int CORE_POOL_SIZE = 5;private static final int MAXIMUM_POOL_SIZE = 128;private static final int KEEP_ALIVE = 10;……private static final ThreadPoolExecutor sExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE,        MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sWorkQueue, sThreadFactory);

可以看到,这里规定同一时刻能够运行的线程数为5个,线程池总大小为128。也就是说当我们启动了10个任务时,只有5个任务能够立刻执行,另外的5个任务则需要等待,当有一个任务执行完毕后,第6个任务才会启动,以此类推。而线程池中最大能存放的线程数是128个,当我们尝试去添加第129个任务时,程序就会崩溃。

因此在3.0版本中AsyncTask的改动还是挺大的,在3.0之前的AsyncTask可以同时有5个任务在执行,而3.0之后的AsyncTask同时只能有1个任务在执行。为什么升级之后可以同时执行的任务数反而变少了呢?这是因为更新后的AsyncTask已变得更加灵活,如果不想使用默认的线程池,还可以自由地进行配置。比如使用如下的代码来启动任务:

Executor exec = new ThreadPoolExecutor(15, 200, 10,TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());new DownloadTask().executeOnExecutor(exec);

这样就可以使用我们自定义的一个Executor来执行任务,而不是使用SerialExecutor。上述代码的效果允许在同一时刻有15个任务正在执行,并且最多能够存储200个任务。

转载自:http://blog.csdn.net/guolin_blog/article/details/11711405

http://blog.csdn.net/hitlion2008/article/details/7983449

更多相关文章

  1. Ubuntu10.04 32位编译Android(安卓)4.0源码
  2. Activity为singleTask模式时的生命周期
  3. android 多线程 — IntentService
  4. 编译生成可执行文件(Android(安卓)studio中)并在android设备中执行
  5. Watchdog 工作机制解析
  6. Activity切换导致的onCreate重复执行
  7. Android(安卓)Audio System 之二:AudioFlinger
  8. 更改Android模拟器中的hosts文件
  9. Android(安卓)Bander设计与实现 - 设计篇

随机推荐

  1. Android中Xposed框架篇—修改系统位置信
  2. Android(安卓)高仿微信6.0主界面 带你玩
  3. Android(安卓)性能优化5 - 内存优化
  4. Android(安卓)Developers:简单的拍照
  5. Android动态布局小结
  6. 关于android面试的几个问题
  7. Android(安卓)Studio 将Library打包成jar
  8. kotlin优雅实现AIDL
  9. Unity在Android(安卓)6.0及以上版本弹出
  10. Android(安卓)NDK 简介、工具安装、环境