BdAsyncTask学习
综述
是什么
BdAsyncTask是仿照系统的AsyncTask重写的异步处理任务。用法和系统原生的AsyncTask一样,复写doInBackground、onPreExecute、onPostExecute、onProgressUpdate等方法
为什么
既然系统已经提供了AsyncTask,我们为何要重写一份BdAsyncTask那?
AsyncTask的缺陷
- 不同的Android版本AsyncTask的实现不同。AsyncTask是1.5版本引入的,当时的是实现是AsyncTask串行的运行在一个后台运行的线程中;1.6改为线程池,允许多个AsyncTask并行执行;从3.0开始为了避免并行执行的一些问题,又改为再一个后台线程中国年执行了。
- 没有优先级控制。在一个app中,根据任务的紧急程度,需要有优先级控制。
- 没有并行度控制。有上下文关系的任务可能需要串行;没有上下文关系的任务可以考虑使用并行,提高效率。
基于以上的原因,我们需要提供一个不依赖系统版本的AsyncTask,并且支持优先级控制,支持并行度控制。
名词解释
优先级
- SUPER_HIGH:线程优先级设置为Process.THREAD_PRIORITY_DEFAULT - 2
- HIGH:线程优先级设置为Process.THREAD_PRIORITY_DEFAULT - 1
- MIDDLE:线程优先级设置为Process.THREAD_PRIORITY_DEFAULT
- LOW:线程优先级设置为Process.THREAD_PRIORITY_BACKGROUND
优先级表示任务的重要程度,图片加载的优先级一般问LOW,网络访问的优先级一般为SUPER_HIGH。
并行度
- SERIAL, // 串行
- TWO_PARALLEL, // 两个任务并行
- THREE_PARALLEL, // 三个任务并行
- FOUR_PARALLEL, // 四个任务并行
- CUSTOM_PARALLEL, // 自定义个数,需要配置num参数,如果不配置,为串行
- MAX_PARALLEL;// 多个任务并行
并行度表示任务和任务之间的关系。比如贴吧IM异步任务就是SERIAL的,保证解析、存库等是串行执行的,不会出现数据错乱。
实现
BdAsyncTaskExecutor中定义了线程池,核心线程数7个,最大线程数256个。
维护了三个队列:waiting、Running、timeout。
执行流程
- 执行BdAsyncTask的execute方法,如果是isSelfExecute则直接new 一个新的Thread执行;否则按照优先级加入到waiting队列中。
- 调度:从waiting队头开始遍历
- 如果任务优先级是SUPER_HIGH,并且没有设置并行度,则立即执行
- 如果任务优先级是HIGH,则判断Running队列中,若正在运行的高、中、低>=核心线程数,则直接返回;否则走步骤3
- 如果任务优先级是MIDDLE,则判断Running队列中,若正在运行的高、中、低>=核心线程数-1,则直接返回。减去1保证有HIGH任务可以尽快执行;否则走步骤3
- 如果任务优先级是LOW,则判断Running队列中,若正在运行的高、中、低>=核心线程数-2,则直接返回。减去2是为了保证有HIGH和MIDDLE任务可以尽快执行;否则走步骤3
- 通过2判断,保证了核心线程池中,还有空余线程供该任务使用。但是这并不能保证该任务一定可以执行,需要判断该任务的并行度,
- 该任务的并行度为SERIAL,如果Running队列中已经有和该任务并行度相同的任务在执行,则继续向后遍历waiting队列;否则走步骤4
- 该任务的并行度为TWO_PARALLEL,如果Running队列中和该任务拥有相同并行度的任务数>=2,继续向后遍历waiting队列;否则走步骤4
- 其他并行度以此类推
通过3,可以获取到真正可以执行的任务,调用BdAsyncTask doinBackground 方法处理耗时操作,同时启动一个超时计时器
在超时时间内,完成任务,则取消超时计时器,并开始下一次调度。如果任务超时,则将任务从Running队列进入timeout队列,并开始下一次调度。timeout队列大小超过总线程数-2*核心线程数后,最老的任务会被取消掉。栗子
mParallel = new BdAsyncTaskParallel(BdAsyncTaskParallelType.SERIAL, BdUniqueId.gen());
//在初始化方法中初始化,只初始化一次,之后使用该mParallel的任务之间就可以并行执行。
//BdUniqueId.gen()保证了唯一性HTTPAsyncTask mTask = new HTTPAsyncTask(m, task);
mTask.setTag(tag);
mTask.setParallel(mParallel);
mTask.setPriority(BdAsyncTaskPriority.SUPER_HIGH);
mTask.execute();
setTag:tag用于标识一类任务,可以通过BdAsyncTask.getTaskNum(tag),获取这个tag的任务数。
setParallel:mParallel表示并行度,如上图中,如果多个HTTPAsyncTask同时执行execute后,则这些task之间是并行执行的,因为这些任务使用了同一个Parallel。类型是BdAsyncTaskParallel;并行度的构造方法:BdAsyncTaskParallel(BdAsyncTaskParallelType type, BdUniqueId tag),用tag来标识唯一标识这个并行度。
BdAsyncTask学习的更多相关文章
- 从直播编程到直播教育:LiveEdu.tv开启多元化的在线学习直播时代
2015年9月,一个叫Livecoding.tv的网站在互联网上引起了编程界的注意.缘于Pingwest品玩的一位编辑在上网时无意中发现了这个网站,并写了一篇文章<一个比直播睡觉更奇怪的网站:直 ...
- Angular2学习笔记(1)
Angular2学习笔记(1) 1. 写在前面 之前基于Electron写过一个Markdown编辑器.就其功能而言,主要功能已经实现,一些小的不影响使用的功能由于时间关系还没有完成:但就代码而言,之 ...
- ABP入门系列(1)——学习Abp框架之实操演练
作为.Net工地搬砖长工一名,一直致力于挖坑(Bug)填坑(Debug),但技术却不见长进.也曾热情于新技术的学习,憧憬过成为技术大拿.从前端到后端,从bootstrap到javascript,从py ...
- 消息队列——RabbitMQ学习笔记
消息队列--RabbitMQ学习笔记 1. 写在前面 昨天简单学习了一个消息队列项目--RabbitMQ,今天趁热打铁,将学到的东西记录下来. 学习的资料主要是官网给出的6个基本的消息发送/接收模型, ...
- js学习笔记:webpack基础入门(一)
之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...
- Unity3d学习 制作地形
这周学习了如何在unity中制作地形,就是在一个Terrain的对象上盖几座小山,在山底种几棵树,那就讲一下如何完成上述内容. 1.在新键得项目的游戏的Hierarchy目录中新键一个Terrain对 ...
- 《Django By Example》第四章 中文 翻译 (个人学习,渣翻)
书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者注:祝大家新年快乐,这次带来<D ...
- 菜鸟Python学习笔记第一天:关于一些函数库的使用
2017年1月3日 星期二 大一学习一门新的计算机语言真的很难,有时候连函数拼写出错查错都能查半天,没办法,谁让我英语太渣. 关于计算机语言的学习我想还是从C语言学习开始为好,Python有很多语言的 ...
- 多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类)
前言:刚学习了一段机器学习,最近需要重构一个java项目,又赶过来看java.大多是线程代码,没办法,那时候总觉得多线程是个很难的部分很少用到,所以一直没下决定去啃,那些年留下的坑,总是得自己跳进去填 ...
随机推荐
- xpath轴的正确使用姿势
网上看了许多关于轴的介绍,只介绍了语法,而没有明说具体实际中该怎么使用,百思不得其解. 背景--python中使用xpath: ----------------------------------- ...
- in a devstack Openstack env, how to start a service, such as aodh-listener
in terminal, when start the service, the service will run in this terminal, and if kill this termina ...
- gulp监听文件变化,并拷贝到指定目录
暂时不支持目录修改.创建.删除var gulp = require('gulp'); var fs = require('fs'); var path = require('path'); var l ...
- UML和UP简介(转载)
UML(统一建模语言,Unified Modeling Language)是用于系统的可视化建模语言. UP(统一过程,Unified Process)是通用的软件开发过程. 很多人或书籍过大的夸大 ...
- Tomcat version 6.0 only supports J2EE 1.2, 1.3, 1.4, and Java EE 5 Web modules的解决办法
前提:用eclipse做项目,新建“Dynamic Web Project”时,“Dynamic web module version”栏里选了3.0版本,部署项目的时候出现了如题的错误. 解决办法: ...
- 对C语言的知识与能力予以自评
看到一个问卷不错,拟作为第三次作业的部分内容. 你对自己的未来有什么规划?做了哪些准备?我准备在将来成为一名合格的软件工作人员,我已经在平时有空的时间里着手代码的练习. 你认为什么是学习?学习有什么用 ...
- 模块化开发--sea.js
当你的网站开发越来越复杂的时候,会经常遇到一下问题吗?1.冲突2.性能3.依赖如果在多人开发或者是复杂的开发过程中会经常遇到这些问 题,就可以用模块化开发来解决.以上问题是如何产生的?1.冲突:如果你 ...
- opencv 人脸识别
背景知识 OpenCV 是一个开源的计算机视觉和机器学习库.它包含成千上万优化过的算法,为各种计算机视觉应用提供了一个通用工具包.根据这个项目的关于页面,OpenCV 已被广泛运用在各种项目上,从 ...
- 统计Apache或Nginx访问日志里的独立IP访问数量的Shell
1.把IP数量直接输出显示: cat access_log_2011_06_26.log |awk '{print $1}'|uniq -c|wc -l 2.把IP数量输出到文本显示: cat acc ...
- oracle rman恢复数据库 方式恢复到异地数据库
目的:从某个环境中,获取相关文件,放到异地机器使用rman 恢复. 情况说明:XX系统使用的是oracle数据库,现已从服务器拉下来相关文件,依靠这些文件来早本地的测试机上恢复数据库,方便进行数据 ...