前言
好久没写博客了,主要是最近公司业务比较忙。今天闲下来,所以补了之前的一个坑。
最初学Rxjava的时候,关于线程,听到了一种理解,深信不疑。具体是什么这里就不说了,怕误导大家。直到逐渐了解了rxjava的源代码,慢慢才揭开了rxjava 线程控制的真实面纱。
关于具体的subscribeOn 和 observeOn 方法的实现原理,在前面的文章中已经进行了详细的介绍,所以这里不再详述。本篇我们会从整体的链式角度来了解线程切换。
引入
首先,根据经验我们知道,不论是什么样的调用链。它的最上层无非就是这样:
首先调用了subscribe进行注册,然后observable会回调onSubscribe方法,但是第二个步骤并不一定会如上图这样调用,下面的例子就会看到,不过并不会影响我们之后的流程分析。
然后observable通知发射源,发射源发射数据。
PS: 第四步画得丑是有原因的,由于这些操作都是在同一个线程中完成的,所以不想让连接线出现在左侧!
实例
那么我们来画一个实例的调用图,先举一个实例类似如下
ObservableX.map.subscribeOn(Thread1).map.observeOn(Thread2).map.subscribe()
链挺长的,包括运行subscribe的线程(Thread0)总共三个线程。
其中ObservableX表示一个任意的Observable。这里我们就用上面的图代替(也许就是Observable.Create)
这张图需要从底部开始往上看,第一步就是在线程t0中调用subscribe。如此往上推,一直到追溯到数据源,数据源开发发送数据(通过onNext等方法)。
我们将右侧的箭头称为上游,因为他是通过追溯的方法一步一步往上层代码运行的。将左侧的箭头称为下游,因为他是反映了真实数据流从最初的发射源一步步发射的过程。
所以从上图可知,subscribeOn方法是将上游线程进行调度,而observeOn方法是调度下游线程。
如果调用链中只定义了subscribeOn的线程,没有定义observeOn的方法,那么下游线程也会被subscribeOn顺便改变(说顺便是由于subscribeOn改变了源数据发送的线程)。
如果存在observeOn,无论在subscribeOn的之前还是之后,都会改变下游线程。
总结
Flowable基本情况相同的!
map,lift 类型的操作符实际上实在subscribe中完成工作内容的,所以处于操作链后方的subscribeOn会修改前面的map中内容的运行线程。
最后一个observerOn会影响最终的subscribe onNext的运行线程