RXJava之线程控制Scheduler(四),Android面试题
前面讲到了,可以利用 subscribeOn()
结合 observeOn()
来实现线程控制,让事件的产生和消费发生在不同的线程。可是在了解了 map()
flatMap()
等变换方法后,有些好事的(其实就是当初刚接触 RxJava 时的我)就问了:能不能多切换几次线程?
答案是:能。因为 observeOn()
指定的是 Subscriber
的线程,而这个 Subscriber
并不是(严格说应该为『不一定是』,但这里不妨理解为『不是』)subscribe()
参数中的 Subscriber
,而是 observeOn()
执行时的当前 Observable
所对应的 Subscriber
,即它的直接下级 Subscriber
。换句话说,observeOn()
指定的是它之后的操作所在的线程。因此如果有多次切换线程的需求,只要在每个想要切换线程的位置调用一次 observeOn()
即可。上代码:
Observable.just(1, 2, 3, 4) // IO 线程,由 subscribeOn() 指定
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.newThread())
.map(mapOperator) // 新线程,由 observeOn() 指定
.observeOn(Schedulers.io())
.map(mapOperator2) // IO 线程,由 observeOn() 指定
.observeOn(AndroidSchedulers.mainThread)
.subscribe(subscriber); // Android 主线程,由 observeOn() 指定
如上,通过 observeOn()
的多次调用,程序实现了线程的多次切换。
不过,不同于 observeOn()
, subscribeOn()
的位置放在哪里都可以,但它是只能调用一次的。
又有好事的(其实还是当初的我)问了:如果我非要调用多次 subscribeOn()
呢?会有什么效果?
这个问题先放着,我们还是从 RxJava 线程控制的原理说起吧。
2) Scheduler 的原理
其实, subscribeOn()
和 observeOn()
的内部实现,也是用的 lift()
。具体看图(不同颜色的箭头表示不同的线程):
subscribeOn()
原理图:
observeOn()
原理图:
从图中可以看出,subscribeOn()
和 observeOn()
都做了线程切换的工作(图中的 “schedule…” 部位)。不同的是, subscribeOn()
的线程切换发生在 OnSubscribe
中,即在它通知上一级 OnSubscribe
时,这时事件还没有开始发送,因此 subscribeOn()
的线程控制可以从事件发出的开端就造成影响;而 observeOn()
的线程切换则发生在它内建的 Subscriber
中,即发生在它即将给下一级 Subscriber
发送事件时,因此 observeOn()
控制的是
它后面的线程。
最后,我用一张图来解释当多个 subscribeOn()
和 observeOn()
混合使用时,线程调度是怎么发生的(由于图中对象较多,相对于上面的图对结构做了一些简化调整):
图中共有 5 处含有对事件的操作。由图中可以看出,①和②两处受第一个 subscribeOn()
影响,运行在红色线程;③和④处受第一个 observeOn()
的影响,运行在绿色线程;⑤处受第二个 onserveOn()
影响,运行在紫色线程;而第二个 subscribeOn()
,由于在通知过程中线程就被第一个 subscribeOn()
截断,因此对整个流程并没有任何影响。这里也就回答了前面的问题:当使用了多个 subscribeOn()
的时候,只有第一个 subscribeOn()
起作用。
3) 延伸:doOnSubscribe()
然而,虽然超过一个的 subscribeOn()
对事件处理的流程没有影响,但在流程之前却是可以利用的。
3) 延伸:doOnSubscribe()
然而,虽然超过一个的 subscribeOn()
对事件处理的流程没有影响,但在流程之前却是可以利用的。
RXJava之线程控制Scheduler(四),Android面试题相关推荐
- 【Android】RxJava的使用(四)线程控制 —— Scheduler
前言 经过前几篇的介绍,对RxJava对模式有了一定的理解:由Observable发起事件,经过中间的处理后由Observer消费.(对RxJava还不了解的可以出门左拐) 之前的代码中,事件的发起和 ...
- RxJava使用(三)Scheduler 线程控制
前言 在默认情况下,即在不指定线程的情况下,RxJava 遵循的是线程不变的原则,即:在哪个线程调用 subscribe(),就在哪个线程生产事件:在哪个线程生产事件,就在哪个线程消费事件. 如果需要 ...
- android rxjava 多线程,你真的了解RxJava的线程切换吗?
使用RxJava可以轻松地实现线程切换,所以在Android中常被用来替代AsyncTask.Handler等原生工具类.使用起来虽然简单,但如果不了解其背后的基本原理,很可能因为使用不当而写出bug ...
- 金三银四的面试黄金季节,Android面试题来了!
金三银四的跳槽季节,你准摆好了吗? 首先我们分享一个Android知识图谱. 下面是一些面试官基本必问的问题,请一定要去了解! 基础知识 – 四大组件(生命周期,使用场景,如何启动) java基础 – ...
- 给初学者的RxJava2.0教程(二):【线程控制】
CSD转载地址:http://blog.csdn.net/qq_23179075/article/details/79256089 作者:Season_zlc 链接:https://www.jians ...
- 20155202 实验四 Android开发基础
20155202 实验四 Android开发基础 实验内容 1.基于Android Studio开发简单的Android应用并部署测试; 2.了解Android.组件.布局管理器的使用: 3.掌握An ...
- 三大通识知识:进程,线程,网络(四)
三大通识知识(一) :进程,线程,网络之间的关系 三大通识知识(二):进程实现原理 三大通识知识(三):线程实现原理 三大通识知识(四):网络 三大通识知识(五):TCP服务器 进程,线程,网络视频连 ...
- Android面试题线程篇
Android面试题线程篇,由本人整理汇总,后续将推出系列篇,如果喜欢请持续关注和推荐. 开启线程的三种方式? java有三种创建线程的方式,分别是继承Thread类.实现Runable接口和使用线程 ...
- android子线程没有运行完,android假如主线程依赖子线程A的执行结果,如何让A执行完成,之后主线程再往下执行呢?...
/* String ObjectResult="原先的结果"; //使用VOLLY框架(与问题无关) JsonObjectRequest jsonObjectRequest = n ...
最新文章
- win7映射网络驱动器消失了_驱动器出现问题怎么办_Win7系统映射网络驱动器出现故障如何解决...
- Spring Cloud Alibaba源码 - 16 Nacos 注册中心源码解析
- 网页MSN,QQ,Skype,贸易通,雅虎通在线客服代码合集
- 计算机系统行业竞争水平,中国计算机等23行业国际竞争力超世界平均水平
- 计算机视觉领域还有那些坑,深度学习/计算机视觉常见的8个错误总结及避坑指南...
- 可扩展的TextView,ExpandableTextView与Scroller类的使用
- Eclipse 答疑:Eclipse 如何更换夜间及外部主题?如何修改代码样式、背景颜色、字体大小?为何注释文字大小不一?
- c++ 多态 运行时多态和编译时多态_C++学习笔记之多态
- 使用Schedule来实现动态的定时任务
- java简单实现一个缓存_java简单实现缓存的三种方法
- 豆瓣电影推荐系统(Ⅰ)ItemCF算法原理
- vba excel 画折线图
- 多个图片合成PDF文件
- python提取图片中的曲线_OpenCV如何提取图片中曲线
- VMware ESX 4.1版本,浏览器无法访问问题【已解决】
- Java黑皮书课后题第5章:5.3(将千克转换成磅)编写程序,显示下面的表格(注意:1kg为2.2磅)
- HarmonyOS 2真的来了!能让不同设备组成“超级终端”
- Python的回溯算法
- 我常用的网站制作工具
- (附源码)计算机毕业设计ssm儿童绘本租赁网站
热门文章
- 使用js的方式设置点击按钮发送短信倒计时并且防止刷新
- 前端登录注册页面、多方式登录功能、腾讯云短信发送功能二次封装(包)、发送短信接口
- 将图像平移到画布中心python_python前端之Photoshop
- 西南科技大学计算机专业全国排名,西南科技大学为什么在全国大学排名很低?...
- 仿射变换affine和透视变换
- HTML网页设计作业个性潮流服装商城模板
- 软件实现串口程序出售,9600收发毫无压力。 采用io管脚模拟,适合串口资源欠缺的芯片使用。 stm32,tms320f28xx,PIC等
- The value of the property 'type' cannot be parsed
- 人机交互基础教程-复习总结
- C语言: “老板,来两份外卖,一份卤肉饭(%d),一份鸡汤面(%f)...“