首页 > 编程语言 > 详细

AsyncTask两种线程池

时间:2020-01-21 12:59:23      阅读:98      评论:0      收藏:0      [点我收藏+]

AsyncTask两种线程池
 http://bbs.51cto.com/thread-1114378-1.html (API 3.0以后):


1.THREAD_POOL_EXECUTOR, 异步线程池
使用
首先创建一个继承自AsyncTask的MyAsyncTask类,然后调用
MyAsyncTask asynct = new MyAsyncTask(task);
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,所以可以直接调用,所以可以有两种调用方法。
a.    asynct.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, 0);
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两种线程池分析和总结”所述)

AsyncTask两种线程池

原文:https://www.cnblogs.com/wytiger/p/12221126.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!