对于RxJava使用subscribeOn和observeOn切换线程的源码解读

本文详细解析了RxJava中subscribeOn和observeOn操作符的源码实现。subscribeOn用于指定订阅时的线程,它会在事件流开始时切换线程,通常用于启动异步任务。observeOn则用于在事件分发过程中切换线程,它会在onNext事件触发时改变执行线程。这两个操作符允许开发者灵活地控制事件流中的线程切换,确保代码在合适的线程中执行。
摘要由CSDN通过智能技术生成

上一篇博客地址:对于RxJava的map操作符的源码解读(推荐先阅读上一篇博客再阅读这一篇)

当我们需要在RxJava的事件流中切换线程来执行代码,也就是使用RxJava的异步事件流编程,我们就需要使用subscribeOn和observeOn来进行切换线程。

那么当我们使用subscribeOn和observeOn来切换线程的时候,源码是怎么做的呢?

subscribeOn

Observable.create(new ObservableOnSubscribe<Object>() {
            @Override
            public void subscribe(ObservableEmitter<Object> emitter) throws Exception {

            }
        })
        .subscribeOn(Schedulers.io())
        .subscribe(new Observer<Object>() {
        	@Override
			public void onSubscribe(Disposable d) {

			}

			@Override
			public void onNext(Object o) {

			}

			@Override
			public void onError(Throwable e) {

			}

			@Override
			public void onComplete() {

			}
		});

这是一段很普通的RxJava代码,我们使用subscribeOn操作符来指定Schedulers里的IO策略,这个策略会创建一个IoScheduler类,这个类内部会封装一个线程池,也就是说我们使用subscribeOn操作符并指定Schedulers的IO策略实质上是使用一个线程池来切换线程,只不过这个线程池的调度RxJava已经帮我们封装好了。

经过上一篇博客,我们已经知道RxJava代码执行是先使用装饰模型封装成一个包裹,然后由这个包裹调用subscribe

对于这段代码而言,我们的第一个包裹是这样的
在这里插入图片描述
(source就是我们在create方法中传入的ObservableOnSubscribe对象,这里使用一个简写)

当这个包裹执行subscribe方法的时候,源码的逻辑其实是这样的
在这里插入图片描述
(executer是一个线程池,SubscribeTask实质上是一个Runnable,其中封装了Observer)

当将SubscribeTask这个Runnable提交到线程池之后,就会执行SubscribeTask中的run方法。此时就切换到了一个新线程来执行接下来的代码。
在这里插入图片描述
根据上一篇博客我们知道,最后在source中传入的是包裹2。在这段代码中,包裹2在调用onNext方法进行事件分发的时候,源码的逻辑是这样的
在这里插入图片描述
至此,关于这段代码的源码解读结束。接下来是关于observeOn操作符的源码解读。

observeOn

直接上一段代码

Observable.create(new ObservableOnSubscribe<Object>() {
            @Override
            public void subscribe(ObservableEmitter<Object> emitter) throws Exception {

            }
        })
        .observeOn(AndroidSchedulers.mainThread())
		.subscribe(new Observer<Object>() {
			@Override
			public void onSubscribe(Disposable d) {

			}

			@Override
			public void onNext(Object o) {

			}

			@Override
			public void onError(Throwable e) {

			}

			@Override
			public void onComplete() {

			}
		});

不多废话了,直接把整个流程的源码解读都贴出来吧
在这里插入图片描述
(HandlerScheduler实质上是一个封装了指定主线程的Handler的类,ObserveOnObserver实质上是一个Runnable,其中封装了Observer)

可以看到和上面的subscribeOn操作符的源码流程差不多,只不过使用observeOn操作符切换线程是在onNext事件分发阶段切换的线程。即上图中Observer.onNext是执行在主线程的。

总结

  • 使用subscribeOn操作符会将从某一层的包裹开始切换线程执行;而observeOn操作符会将从某一个onNext开始切换线程。
  • 直接从代码上来说就是subscribeOn操作符会指定该操作符的上一个操作符及其之后的所有语句执行在新的线程(这是之后没有使用observeOn操作符的情况,之后使用了observeOn操作符会切换成新的线程);而observeOn操作符会指定下一个onNext及其之后所有OnNext执行在新的线程。
  • subscribeOn操作符只会以第一个指定的为准;而observeOn操作符可以使用很多次。因为我们通过以上的解读可以知道subscribeOn操作符是从某一层的包裹开始切换线程执行,那么这个线程切换就会以包裹在最里面的那一层ObservableSubscribeOn切换的线程为准;而observeOn操作符是从某一个onNext开始切换线程,因此可以不同的onNext执行在不同的线程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

48k纯贱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值