RxJava系列7:线程切换 Scheduler

##一.Scheduler

默认情况下rxjava中生产者和订阅者都是在当前线程中执行。Scheduler就是用来切换生产者和订阅者执行的线程。

Scheduler默认内置了一些内置的Scheduler,方便针对不同的任务选择.

在这里插入图片描述

##二.subscribeOn & ObserveOn
subscribeOn指定subscribe()所发生的线程,或者叫做事件产生的线程
observeOn 指定 Subscriber 所运行在的线程,或者叫做事件消费的线程

##三.多次调用subscribeOn & ObserveOn,不同操作符所在线程执行问题

上面了解了rxjava线程调度的基本知识。这里抛出一个问题:一般一个生产者会经过多个操作符的处理,最后流到订阅者由订阅者处理。如果在多个操作符执行过程中多次调用subscribeOn和ObserveOn,那怎么判断这些操作运行的线程呢?

我写了一个小demo,如下:

                Observable
                        .create(new Observable.OnSubscribe<Integer>() {
                            @Override
                            public void call(Subscriber<? super Integer> subscriber) {
                                //main
                                Log.d("thread10", "map method in thread: " + Thread.currentThread().getName());
                                subscriber.onNext(1);

                            }
                        })
                        .subscribeOn(AndroidSchedulers.mainThread())
                        .observeOn(Schedulers.io())
                        .map(new Func1<Integer, Integer>() {
                            @Override
                            public Integer call(Integer integer) {
                                //io
                                Log.d("thread11", "map method in thread: " + Thread.currentThread().getName());
                                return integer;
                            }
                        })
                        .observeOn(AndroidSchedulers.mainThread())
                        .map(new Func1<Integer, Integer>() {
                            @Override
                            public Integer call(Integer integer) {
                                //main
                                Log.d("thread12", "map method in thread: " + Thread.currentThread().getName());
                                return integer;
                            }
                        })
                        .observeOn(Schedulers.io())
                        .map(new Func1<Integer, Integer>() {
                            @Override
                            public Integer call(Integer integer) {
                                //io
                                Log.d("thread13", "map method in thread: " + Thread.currentThread().getName());
                                return integer;
                            }
                        })
                        .observeOn(AndroidSchedulers.mainThread())
                        .map(new Func1<Integer, Integer>() {
                            @Override
                            public Integer call(Integer integer) {
                                //main
                                Log.d("thread14", "map method in thread: " + Thread.currentThread().getName());
                                return integer;
                            }
                        })
                        .observeOn(Schedulers.io())
                        .subscribe(new Subscriber<Integer>() {
                            @Override
                            public void onCompleted() {

                            }

                            @Override
                            public void onError(Throwable e) {

                            }

                            @Override
                            public void onNext(Integer integer) {
                                //io
                                Log.d("thread15", "map method in thread: " + Thread.currentThread().getName());
                                System.out.print(integer + '\n');
                            }
                        });

02-09 14:13:50.245 12755-12755/com.sankuai.moviepro D/thread10: map method in thread: main
02-09 14:13:50.246 12755-13004/com.sankuai.moviepro D/thread11: map method in thread: RxIoScheduler-5
02-09 14:13:50.246 12755-12755/com.sankuai.moviepro D/thread12: map method in thread: main
02-09 14:13:50.246 12755-13007/com.sankuai.moviepro D/thread13: map method in thread: RxIoScheduler-8
02-09 14:13:50.246 12755-12755/com.sankuai.moviepro D/thread14: map method in thread: main
02-09 14:13:50.246 12755-13006/com.sankuai.moviepro D/thread15: map method in thread: RxIoScheduler-7

上面打印出了具体的输出。这里不从源码角度分析线程调度,直接给结论,大家可以先记住。后面会简要分析rxjava的源码,到时候会具体分析线程调度这块内容。

结论:

  • subscribeOn(Schedulers.io())影响的是他前面执行所在的线程,而observeOn(AndroidSchedulers.mainThread())影响的是他后面执行所在的线程。

  • subscribeOn()它指示Observable在一个指定的调度器上创建(只作用于被观察者创建阶段)。只能指定一次,如果指定多次则以第一次为准

  • observeOn()指定在事件传递(加工变换)和最终被处理(观察者)的发生在哪一个调度器。可指定多次,每次指定完都在下一步生效。

//new Observable.just()执行在新线程
  Observable.create(new Observable.just(getFilePath())
           //指定在新线程中创建被观察者
          .subscribeOn(Schedulers.newThread())
          //将接下来执行的线程环境指定为io线程
          .observeOn(Schedulers.io())
            //map就处在io线程
          .map(mMapOperater)
            //将后面执行的线程环境切换为主线程,
            //但是这一句依然执行在io线程
          .observeOn(AndroidSchedulers.mainThread())
          //指定线程无效,但这句代码本身执行在主线程
          .subscribeOn(Schedulers.io())
          //执行在主线程
          .subscribe(mSubscriber);

##四.subscribe的onError和doOnError有什么区别

Observable.just(1, 2, 3).concatWith(Observable.error(new Error()))
                .subscribeOn(Schedulers.newThread())
                .doOnError(new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        Log.d("eror", "doonerror");
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<Integer>() {
                    @Override
                    public void call(Integer integer) {

                    }
                }, new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        Log.d("eror", "onerr");
                    }
                });

如果不涉及多线程,onError和doOnError无区别。但是这里涉及多线程。
doOnError是在子线程中执行,eror在主线程中执行。

##参考资料:
理解RxJava的线程模型
http://www.importnew.com/23325.html

简单谈谈RxJava和多线程并发
http://www.jb51.net/article/107313.htm

RxJava中多线程机制
http://blog.csdn.net/yaoyasong/article/details/50666743

RxJava - 小心 observeOn 的陷阱
https://www.jianshu.com/p/238b286ac69c

【译】在正确的线程上观察
https://www.jianshu.com/p/72911b9ba2d7

RxJava中的doOnSubscribe默认执行线程分析
http://blog.csdn.net/jdsjlzx/article/details/59223182

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值