继上篇,关于Rxjava,让你知道什么叫“大海无量”

话题

通过上一篇我们分析了RxJava的订阅,以及RxJava常见的面试问题。在上一篇我们分析过多次调用subscribeOn只有第一次调用的时候有效,原因是因为最开始调用的subscribeOn返回的observable会把后面执行的subscribeOn返回的observable给覆盖了,因此我们感官的是只有第一次的subscribeOn能生效。实际中间每一个Observable生成的时候还是会有指定的线程的,只是在最上游的observable只接收第一次的subscribeOn指定的线程,那么我们可以通过doOnSubscribe监测中间的observable确实有自己的线程,这是我们这节探讨的话题。

前一节分析了通过observeOn指定了紧跟其后的observer的线程,如果我们多次调用observeOn,其实是最后一次observeOn才有效指定observer的线程,那我们可以通过doOnNext来监听每一次的observeOn线程的切换,这是我们这节探讨的话题。

如果我们没指定observer的线程,只指定了observable的线程,则observer的线程则会跟observable的线程一起走的,也就是我们只设置了subscribeOn,而没有设置observeOn的情况。这是我们这节探讨的话题。

上一节我们简单的提过背压,那么背压是什么呢,以及Flowable怎么能控制背压也是我们这节讨论的话题。

这节探讨的话题

  • doOnSubscribe是怎么做到监听中间的observable的线程?
  • doOnNext是怎么做到监听每一次observeOn线程的切换,以及map的apply方法的线程有谁控制?
  • 如果不指定observer的线程,也就是指设置subscribeOn,而不设置observeOn,那observer的线程是什么样的?
  • 背压是什么,以及Flowable怎么能控制背压?

doOnSubscribe的监听

在上一节我们介绍过subscribeOn是控制上游的observable在哪个线程执行,关于怎么控制上游的observable可以看我上篇文章,那如果多次执行subscribeOn的时候,Observable接收的是第一次的subscribeOn指定的线程,因为每次设置都会被上一层subscribeOn设置的线程所覆盖了,这里的覆盖是对于最上游的Observable而言的,中间生成的Observable其实是有线程切换的,我们可以通过doOnSubscribe来监听每一次subscribeOn线程的切换,我们还是拿例子来说:

在上一篇文章我们已经说过,订阅是从最下游的observer到上面一层一层的observable,所以我们最下游的observable开始发生订阅,也就是①处通过subscribeOn生成的ObservableSubscribeOn观察者开始订阅,它会在订阅方法中,给它的上游的observable添加订阅,也就是②号处通过doOnSubscribe生成的ObservableDoOnLifecycle观察者开始订阅,然后在它的订阅里面给③号订阅,③号给④号添加订阅,最后到最上游的observable发生订阅,也就是最上游的ObservableOnSubscribe的subscribe方法被调用。这就是从下到上依次订阅的顺序,下面以一张图说明订阅顺序:

那什么时候doOnSubscribe的内部类Consumer的accept方法什么调用呢?

我们直接看上面的图,它是在上一个Observable,也就是doOnSubscribe生成的ObservableDoOnLifecycle里面的装饰observer(DisposableLambdaObserver)监听到订阅的时候调用的。而在该例子中②号、④号通过doOnSubscribe生成的observable的上游observable是subscribeOn生成的,而subscribeOn最终是生成了ObservableSubscribeOn的observable,在它的订阅里面是直接给下游的observer添加订阅监听了:

所以由上面可知②号处的doOnSubscribe打印是在③号上游的subscribeOn发生订阅的时候,所以它最先打印出结果,再一次是④号打印出结果,最后是最上游的observable的订阅打印。那每一处的doOnSubscribe中accept接收到的线程是怎么回事呢,这个我先说结论,是跟它下面的subscribeOn指定的线程保持一致。所以②号处打印是①号处指定的线程,④号是③号处指定的线程打印,后面我们分析doOnSubscribe时候说。

上一节我们知道subscribeOn是指定它上游的observable订阅发生的线程,而doOnSubscribe操作符最终也是生成了一个ObservableDoOnLifecycle的observable,所以可以这么说ObservableDoOnLifecycle的订阅发生的线程是由紧跟它后面的subscribeOn指定的线程所决定的。
而在ObservableDoOnLifecycle的订阅方法中,它是直接订阅了上游的observable,在上面示例中也就是第二个observableObservableDoOnLifecyclesubscribeActual方法如下:
上一篇介绍了在每一个Observable的订阅方法中,会先创建装饰的observer,并且把下游的observer传到创建的装饰的observer中,接着会给下游的observer添加订阅的回调,接着会给上游的observable添加订阅,而在此处的ObservableDoOnLifecycle订阅方法中先是创建了DisposableLambdaObserver的装饰observer,接着给上游的observable添加订阅。那给下游的obserer添加订阅的监听呢,这就放在了DisposableLambdaObserver的装饰observer的onSubscribe中了。

由于上面我们通过doOnSubscribe生成最下游的observable(ObservableDoOnLifecycle)的订阅线程是io线程,所以它的上游observable也是io线程,我们还没分析完doOnSubscribe传进去的Consumer的accept方法发生的线程,这个需要我们看下上面分析的ObservableDoOnLifecycle订阅中创建的装饰DisposableLambdaObserver:

上面一上来就是给传进来的Consumer执行了accept的回调,紧接着给下游的observer添加订阅的监听,方便下游的observer能收到订阅的回调啊,是不是这么回事呢?

那此处装饰的observer(DisposableLambdaObserver)订阅监听是由谁发起的呢,肯定是上游的observable开始订阅的时候发起的下游observer订阅监听啊,而上面我们分析了此处的上游observable订阅线程是由紧挨doOnSubscribesubscribeOn决定的,所以此处不难看出最终doOnSubscribe中的consumer监听的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值