您的位置:首页 > 其它

AsyncTask两种线程池

2016-05-26 22:47 120 查看
AsyncTask两种线程池
http://bbs.51cto.com/thread-1114378-1.html (API 3.0以后):

1.THREAD_POOL_EXECUTOR, 异步线程池

使用

首先创建一个继承自AsyncTask的MyAsyncTask类,然后调用

1
MyAsyncTask asynct =
new
MyAsyncTask(task);
2
asynct.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,
0
);
原理
1.
corePoolSize
=CPU核心数+1;
2.
maximumPoolSize
=2倍的CPU核心数+1;
3.核心线程无超时机制,非核心线程在闲置时间的超时时间为
1s

4.任务队列的容量为
128


当一个任务通过asynct.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,0)方法欲添加到线程池时:

如果此时线程池中的数量小于corePoolSize,即使线程池中的线程都处于空闲状态,也要创建新的线程来处理被添加的任务。

如果此时线程池中的数量等于 corePoolSize,但是缓冲队列 workQueue未满,那么任务被放入缓冲队列。

如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量小于maximumPoolSize,建新的线程来处理被添加的任务。

如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量等于maximumPoolSize,那么通过 handler所指定的策略来处理此任务。

当线程池中的线程数量大于 corePoolSize时,如果某线程(非核心线程)空闲时间超过keepAliveTime,线程将被终止。这样,线程池可以动态的调整池中的线程数。

也就是:处理任务的优先级为:
核心线程corePoolSize、任务队列workQueue、最大线程maximumPoolSize,如果三者都满了,使用handler处理被拒绝的任务(一般为抛出java.util.concurrent.RejectedExecutionException异常)。



2.SERIAL_EXECUTOR,同步线程池
使用
它是默认的Executor,所以可以直接调用,所以可以有两种调用方法。

1
a.    asynct.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR,
0
);
2
b.    asynct.execute(
0
);
原理
SERIAL_EXECUTOR在THREAD_POOL_EXECUTOR的基础上添加了一个mTasks的集合来保证任务顺序执行(异步)

AsyncTask在不同SDK版本中的区别
http://zmywly8866.github.io/2015/09/29/android-call-asynctask-excute-not-run.html:如上述,默认使用异步
旧版本

  通过查阅官方文档发现,AsyncTask首次引入时,异步任务是在一个独立的线程中顺序地执行,也就是说一次只能执行一个任务,不能并行地执行,从1.6开始,AsyncTask中引入了线程池,支持同时执行5个异步任务,也就是说同时只能有5个线程运行,超过的线程只能等待,等待前面的线程某个执行完了才被调度和运行。换句话说,如果一个进程中的AsyncTask实例个数超过5个,那么假如前5个都运行很长时间的话,那么第6个只能等待机会了。这是AsyncTask的一个限制,而且对于2.3以前的版本无法解决。如果你的应用需要大量的后台线程去执行任务,那么你只能放弃使用AsyncTask,自己创建线程池来管理Thread,或者干脆不用线程池直接使用Thread也无妨。不得不说,虽然AsyncTask较Thread使用起来比较方便,但是它最多只能同时运行5个线程,这也大大局限了它的实力,你必须要小心的设计你的应用,错开使用AsyncTask的时间,尽力做到分时,或者保证数量不会大于5个,否则就可能遇到上面提到的问题。

从1.6开始,AsyncTask中引入的线程池:

1、线程池中的工作线程少于5个时,将会创建新的工作线程执行异步任务(红色表示新任务,下同)



2、线程池中已经有5个线程,缓冲队列未满,异步任务将会放到缓冲队列中等待



3、线程池中已经有5个线程,缓冲队列已满,那么线程池将新开工作线程执行异步任务



问题:Android的设备一般不超过2个cpu核心,过多的线程会造成线程间切换频繁,消耗系统资源。

4、线程池中已经有128个线程,缓冲队列已满,如果此时向线程提交任务,将会抛出RejectedExecutionException



问题:抛出的错误不catch的话会导致程序FC。

来源: http://blog.csdn.net/mylzc/article/details/6784415

新版本
可能是Google意识到了AsyncTask的局限性了,从Android 3.0开始对AsyncTask的API做出了一些调整:每次只启动一个线程执行一个任务,完成之后再执行第二个任务,也就是相当于只有一个后台线程在执行所提交的任务
(如上 “Android AsyncTask两种线程池分析和总结”所述)

来自为知笔记(Wiz)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: