大约Android 3.0后AsyncTask默认的单线程分析
在Android下了很大的后台操作在需要的情况下。通常用于AsyncTask这个类。比方说,网络负载形象。访问server接口。一般的情况是使用一个的一例AsyncTask对象mTask,复制AsyncTask抽象方法doinBackgroud等等,最后运行task.execute(params),然后就能够在UI线程上方便的取得后台线程的运行结果;
AsyncTask运行中终于触发的是把任务交给线池THREAD_POOL_EXECUTOR来运行,提交的任务并行的在线程池中运行。但这些规则在3.0之后发生了变化,3.0之后提交的任务是串行运行的。运行完一个任务才运行下一个!
先看看3.0曾经的代码;
private static final int CORE_POOL_SIZE = 5;
private static final int MAXIMUM_POOL_SIZE = 128;
private static final int KEEP_ALIVE = 10;
</pre><p></p><pre>
public static final Executor THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE,TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);
3.0曾经线程池里核心线程有5个,同一时候存在的线程数最大不能超过128个。线程池里的线程都是并行执行的。
可是在3.0之后,直接调用execute(params)触发的是sDefaultExecutor的execute(runnable)方法。而不是原来的THREAD_POOL_EXECUTOR
private static final int CORE_POOL_SIZE = CPU_COUNT + 1;
private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
private static final int KEEP_ALIVE = 1;
public static void execute(Runnable runnable) {
sDefaultExecutor.execute(runnable);
}
看看这个sDefaultExecutor与原来的THREAD_POOL_EXECUTOR线程池有什么 区别,sDefaultExecutor实际上是指向SerialExecutor的一个实例,从名字上看是一个顺序运行的executor;
public static final Executor SERIAL_EXECUTOR = new SerialExecutor();
private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR; 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,当提交一个任务。运行一次execute(),向mTasks加入一个runnable。此时mActive为null。接着会运行scheduleNext(),将mActive指向刚刚加入的runbale,并提交到THREAD_POOL_EXECUTOR中运行,接着就线程池中就会运行以下这段代码。
try {
r.run();
} finally {
scheduleNext();
}
当asyncTask提交大量的任务时。会反复之前的流程。任务都加入至mTasks中了,提交第一个任务之后,mActive便不再为Null了,之后的任务假设要被运行就必需等到前一个任务run方法跑完,也就是try{ }语句块中的run(),前一个任务运行完后,才会调用finally
后面的scheduleNext()从mTasks中取出下一个任务来运行。
分析完上面的代码后,如今对于3.0以后AsyncTask默认情况下同一时候仅仅存在一个线程顺序运行的原理就了解清楚了;
假设想要提交的任务在能并行运行呢?这在网络图片显示中还是比較实用的;
AsyncTask也为我们提供了第二种启动方法
public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,Params... params)
这里能够指定自己定义的executor,而不再用SerialExecutor,假设乐意的话当然也能够直接使用用原本的THREAD_POOL_EXECUTOR,这样就能够保证多个任务并行运行了。
版权声明:本文博客原创文章,博客,未经同意,不得转载。
大约Android 3.0后AsyncTask默认的单线程分析的更多相关文章
- IIS6(Win2003) 使用.net 4.0 后,默认文档失效解决方案。
IIS6(Win2003) 使用.net framework 4.0 后,默认文档失效解决方案. 用.net framework 4.0 开发的WEB项目,但放到iis6 中无法使用默认文档,状况如下 ...
- android 4.0后不允许屏蔽掉home键
屏蔽home键的方法 // 屏蔽掉Home键 public void onAttachedToWindow() { this.getWindow().setType(WindowManager.Lay ...
- Android Studio安装后配置默认新工程目录以及.gradle,.android,.m2和system,config目录
关于在哪里设置:以下所有设置都是在没有打开工程的前提下设置的, Configure > Settings 如图: 不要使用 Configure > Project Defaults> ...
- 转 Android 4.0后,自定义Title报错 You cannot combine custom titles with other title feature
自定义Titlebar时为了避免冲突 需要修改:AndroidManifest.xml android:theme="@style/mystyle" styles.xml文件中 ...
- Android 6.0 M userdebug版本执行adb remount失败
[FAQ18076]Android 6.0 M版本默认会打开system verified boot,即在userdebug和user版本会把system映射到dm-0设备,然后再挂载.挂载前会检查s ...
- Android 5.0之后屏幕截图的方法
截图的几种方法 Android获取屏幕截图主要有以下三种方法 1.通过view.getDrawingCache()获取指定View的绘制缓存来实现截屏. 这种方式Android 5.0之前也可以,且不 ...
- Android权限管理之RxPermission解决Android 6.0 适配问题
前言: 上篇重点学习了Android 6.0的运行时权限,今天还是围绕着Android 6.0权限适配来总结学习,这里主要介绍一下我们公司解决Android 6.0权限适配的方案:RxJava+RxP ...
- Android 5.0之前屏幕截图的方法
截图的几种方法 Android获取屏幕截图主要有以下三种方法 1.通过view.getDrawingCache()获取指定View的绘制缓存来实现截屏. 这种方式Android 5.0之前也可以,且不 ...
- Android 9.0适配遇到的问题1
文章同步自javaexception 本周在适配Android 9.0,过程中碰到了小问题 问题1: SSL handshake timed out 解决办法: Android 9.0 开始,默认不允 ...
随机推荐
- 策略模式设计模式(Strategy)摘录
23种子GOF设计模式一般分为三类:创建模式.结构模型.行为模式. 创建模式抽象的实例.一个系统独立于怎样创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而一个对象创建型模式将 ...
- Group By去除重复数据
今天在写一个sql,目的是去除表里某一个字段相同的数据,只保留最新的一条.之前group by 用的少.特此记录一下. SELECT * FROM litb_approval_task SELECT ...
- ASP.NET MVC5 插件机制中插件的简单实现
Autofac 依赖注入 ASP.NET MVC5 插件机制中插件的简单实现 一.前言 由于项目业务复杂,创建了多个插件并把他们放在了不同的项目中,项目使用AutoFac做的IOC:但是主项目可以注入 ...
- 三星Galaxy s4(i9505)得到完美root权限教程
三星Galaxy s4(i9505)完美获取root权限教程 论坛上贴吧上关于三星s4 i9505 root的介绍有非常多,方法多种多样.今天小编来介绍一种使用root软件来实现三星i9505一键ro ...
- iOS开发必看的博客汇总
OneV's Den http://onevcat.com/ 沉船家园 http://beyondvincent.com/ NSHipster http://nshipster.cn/ Limboy ...
- 【SSH三个框架】Hibernate第十篇基础:inverse属性具体解释
inverse后经常用于双向1-N在相关性.它也可以在使用N-N该协会,这里,例如用双1-N联想 或两个与各部门及工作人员,两javabean没有写. 首先,我们的员工看映射文件: <?xml ...
- C#操作Xml:通过XmlDocument读写Xml文档
什么是Xml? Xml是扩展标记语言的简写,是一种开发的文本格式.关于它的更多情况可以通过w3组织了解http://www.w3.org/TR/1998/REC-xml-19980210.如果你不知道 ...
- cralwer_爬虫代理中心的简要设计
代理中心: 简单讲: 精细化控制限制资源的使用,保证有限资源的充分利用及有效性.支持动态增减,实时更新. 需求 rest api提供请求输入与输出 客户端使用代理心跳接收,用于更新代理的使用次数,被占 ...
- linux_sed 正则替换
目标 替换 test.data文件中的 原正则: (\d{4}[^)]*?) sed不支持 \d 改为0-9 测试 :head test.data| sed -r "s/([0-9]{4}[ ...
- php_windows搭建
Php文件放到: D:\web\Apache2.2\htdocs 修改 D:\web\PHP\php.ini 拓展 修改 D:\web\Apache2.2\conf\httpd.conf 支持php ...