关于android并发
AsyncTask在android2.3的时候线程池是一个核心数为5线程,队列可容纳10线程,最大执行128个任务,这存在一个问题,当你真的有138个并发时,即使手机没被你撑爆,那么超出这个指标应用绝对crash掉。 后来升级到4.0,为了避免并发带来的一些列问题,AsyncTask竟然成为序列执行器了,也就是你即使你同时execute N个AsyncTask,它也是挨个排队执行的。 这一点请同学们一定注意,AsyncTask在4.0以后,是异步的没错,但不是并发的。使用系统的AsyncTask过程中,cancel方法也会出现停止不了的异常,遇到多任务网络处理时,会出现线程混乱的情况。
异步任务AsyncTask核心
并发量的设置,默认为当前手机的CPU个数
private static int CPU_COUNT=Runtime.getRuntime().availableProcessors();
声明一个FutureTask的计算任务,并定义实现Callable的WorkerRunnable
private static abstract class WorkerRunnable implements Callable { Params[]mParams; }
如图一所示,最后任务在call()方法中被执行。
其中核心是定义一个任务调度模块,可以自定义一个如下的简易调度器,并调用刚才的mFuture。
Executor mSmartExecutor = Executors.newFixedThreadPool(4);
exec.execute(mFuture);
此调度器支持同时处理4个任务,之后的任务需等待执行。
当然,有些场景这个调度器并不能发挥作用。当出现瞬间大量并发的场景,比如,假设用户拖动时如果需要启动大量异步线程,而拖动过去时间很久的用户已经看不到,这时候就允许之前图片加载的任务丢失。它大大改善Android自带异步任务框架的处理能力和速度。默认地,它使用LIFO(后进先出)策略来调度线程,可将最新的任务快速执行,当然你自己可以换为FIFO调度策略。这有助于用户当前任务优先完成(比如加载图片时,很容易做到当前屏幕上的图片优先加载)。
此图定义了一个用于特殊场景的调度器。
注意:AsyncTask中的调度器变量需用static修饰,若不然,每次新建AsyncTask都会新建一个线程池,而AsyncTask的核心是公用一个调度器。
public static final Executor mLruSerialExecutor=new SmartSerialExecutor();
当task执行完doInBackground方法后,定义InternalHandler去处理返回值
最后实现FinishedListener,让用户处理结果。
AsyncTask的衍生扩展
SafeTask:安全异步任务,可以捕获任意异常,并反馈给给开发者。
SimpleTask:简单的异步任务,仅仅指定返回结果的类型,不可输入参数.
CachedTask:主要用于获取网络数据,给它一个缓存时间,只要未超时,它将先从本地获取,仅当超时或本地获取失败时才去真正联网完成。