Rxjava源码(三)-----线程控制Scheduler
来源:互联网 发布:servo guide软件下载 编辑:程序博客网 时间:2024/05/17 07:05
又是一个令人激动的东西,真不想说废话了,开始神奇之旅吧(原谅我这么土鳖,就是觉得很神奇,不看不知道,一看吓一跳啊)
灵活的变换已经让我们眼花缭乱了,线程的自由控制更是让RxJava的牛叉之气更上一层楼。
前边我们已经知道了可以利用subscribeOn()结合observeOn()来实现线程控制,让事件的产生和消费发生在不同的线程,map() flatMap()等方法都可以多次变换,那线程切换能不能多次呢?
答案当然是能啦,因为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(),subscribeOn()的位置放哪里都可以,但是它只能调用一次,那如果非要调用多次呢,这个问题我们从线程控制的原理开始说起吧
Scheduler原理:
subscribeOn()和observeOn()的内部实现,也是用了lift()方法,
先看observeOn()吧:
public final Observable<T> observeOn(Scheduler scheduler) { if (this instanceof ScalarSynchronousObservable) { return ((ScalarSynchronousObservable<T>)this).scalarScheduleOn(scheduler); } return lift(new OperatorObserveOn<T>(scheduler)); }这里分为了两种情况,第一种情况Observable是由just方法创建的,我们看看他的走向:
public Observable<T> scalarScheduleOn(Scheduler scheduler) { if (scheduler instanceof EventLoopsScheduler) { EventLoopsScheduler es = (EventLoopsScheduler) scheduler; return create(new DirectScheduledEmission<T>(es, t)); } return create(new NormalScheduledEmission<T>(scheduler, t)); }这里可以看到根据Scheduler的类型又分为两种情况,不过都是创建一个新的Observable<T>对象。那么不同的就是两个OnSubscribe<T>对象了,一个是DirectScheduledEmission,另一个是NormalScheduleEmission。
/** Optimized observeOn for scalar value observed on the EventLoopsScheduler. */ static final class DirectScheduledEmission<T> implements OnSubscribe<T> { private final EventLoopsScheduler es; private final T value; DirectScheduledEmission(EventLoopsScheduler es, T value) { this.es = es; this.value = value; } @Override public void call(final Subscriber<? super T> child) { child.add(es.scheduleDirect(new ScalarSynchronousAction<T>(child, value))); } }
/** Emits a scalar value on a general scheduler. */ static final class NormalScheduledEmission<T> implements OnSubscribe<T> { private final Scheduler scheduler; private final T value; NormalScheduledEmission(Scheduler scheduler, T value) { this.scheduler = scheduler; this.value = value; } @Override public void call(final Subscriber<? super T> subscriber) { Worker worker = scheduler.createWorker(); subscriber.add(worker); worker.schedule(new ScalarSynchronousAction<T>(subscriber, value)); } }
/** Action that emits a single value when called. */ static final class ScalarSynchronousAction<T> implements Action0 { private final Subscriber<? super T> subscriber; private final T value; private ScalarSynchronousAction(Subscriber<? super T> subscriber, T value) { this.subscriber = subscriber; this.value = value; } @Override public void call() { try { subscriber.onNext(value); } catch (Throwable t) { subscriber.onError(t); return; } subscriber.onCompleted(); } }
。。。。。。。再来看一下subscribeOn()
public final Observable<T> subscribeOn(Scheduler scheduler) { if (this instanceof ScalarSynchronousObservable) { return ((ScalarSynchronousObservable<T>)this).scalarScheduleOn(scheduler); } return nest().lift(new OperatorSubscribeOn<T>(scheduler)); }
这里我不想先分析第一种情况了,先来看第二种情况吧:
nest()函数干了啥:
public final Observable<Observable<T>> nest() { return just(this); }
so easy,调用了just方法,但是请注意,这里的this,把最原始的这个Observable当做参数传入了,
public final static <T> Observable<T> just(final T value) { return ScalarSynchronousObservable.create(value); }还是来复习看一下这个ScalarSynchronousObservable吧
public final class ScalarSynchronousObservable<T> extends Observable<T> { public static final <T> ScalarSynchronousObservable<T> create(T t) { return new ScalarSynchronousObservable<T>(t); } private final T t; protected ScalarSynchronousObservable(final T t) { super(new OnSubscribe<T>() { @Override public void call(Subscriber<? super T> s) { /* * We don't check isUnsubscribed as it is a significant performance impact in the fast-path use cases. * See PerfBaseline tests and https://github.com/ReactiveX/RxJava/issues/1383 for more information. * The assumption here is that when asking for a single item we should emit it and not concern ourselves with * being unsubscribed already. If the Subscriber unsubscribes at 0, they shouldn't have subscribed, or it will * filter it out (such as take(0)). This prevents us from paying the price on every subscription. */ s.onNext(t); s.onCompleted(); } }); this.t = t; } // 暂且省略无关代码
看到这个ScalarSynchronousObservable对象,我们此时需要记住的是:原始Observable被当做一个属性保存在ScalarSynchronousObservable对象中,看图:
以上是nest()函数调用以后发生的事情,接着开始看lift()函数:先复习一下原来我们分析的lift原理图:
lift方法会创建一个Observable<T>对象,该对象的内部有一个OnSubscribe<T>对象,它的call方法会调用OperatorSubscribeOn.call方法得到一个Subscriber<Observable<T>>对象,并在调用上面的Observable<Observable<T>>.OnSubscribe<Observable<T>>.call方法时传递进去。那么来看下OperatorSubscribeOn.call是如何将一个Subscribe<T>转换成Subscriber<Observable<T>>对象的。
public class OperatorSubscribeOn<T> implements Operator<T, Observable<T>> { private final Scheduler scheduler; public OperatorSubscribeOn(Scheduler scheduler) { this.scheduler = scheduler; } @Override public Subscriber<? super Observable<T>> call(final Subscriber<? super T> subscriber) { final Worker inner = scheduler.createWorker(); subscriber.add(inner); return new Subscriber<Observable<T>>(subscriber) { @Override public void onCompleted() { // ignore because this is a nested Observable and we expect only 1 Observable<T> emitted to onNext } @Override public void onError(Throwable e) { subscriber.onError(e); } @Override public void onNext(final Observable<T> o) { inner.schedule(new Action0() { @Override public void call() { final Thread t = Thread.currentThread(); o.unsafeSubscribe(new Subscriber<T>(subscriber) { @Override public void onCompleted() { subscriber.onCompleted(); } @Override public void onError(Throwable e) { subscriber.onError(e); } @Override public void onNext(T t) { subscriber.onNext(t); } @Override public void setProducer(final Producer producer) { subscriber.setProducer(new Producer() { @Override public void request(final long n) { if (Thread.currentThread() == t) { // don't schedule if we're already on the thread (primarily for first setProducer call) // see unit test 'testSetProducerSynchronousRequest' for more context on this producer.request(n); } else { inner.schedule(new Action0() { @Override public void call() { producer.request(n); } }); } } }); } }); } }); } }; }}
可以看到OperatorSubscribeOn对象的call方法里面实例化了一个Subscriber<T>对象并返回。该Subscriber<T>的onNext方法中会调用Scheduler.schedule将一个Action0加入线程池里执行,该Action0的call方法会触发原始Observable<T>的unsafeSubscribe方法,然后会触发原始OnSubscribe<T>.call方法,也就是说原始OnSubscribe<T>.call方法是在切换后的线程中执行。如图
- Rxjava源码(三)-----线程控制Scheduler
- RxJava使用(三)Scheduler 线程控制
- RxJava使用(三)Scheduler 线程控制
- 【RxJava 实践系列】(三)线程控制 — Scheduler
- RxJava--Scheduler (线程控制 )
- RxJava学习笔记(三)--- 线程调度Scheduler
- RxJava线程控制 —— Scheduler (一)
- RXJava——线程控制:Scheduler (二)
- Rxjava学习(三线程调度器Scheduler)
- Android RxJava的使用(四)线程控制 —— Scheduler
- 【Android】RxJava的使用(四)线程控制 —— Scheduler
- 【Android】RxJava的使用(四)线程控制 —— Scheduler
- Android RxJava的线程控制 —— Scheduler
- RXJava——线程控制 —— Scheduler (一)
- Rxjava中的线程控制 —— Scheduler (一)
- RxJava(11-线程调度Scheduler)
- RxJava 源码解读分析 Scheduler
- rxjava(三)Subject与Scheduler
- Leetcode 3. Longest Substring Without Repeating Characters
- 关于Maven+SpringMvc4.2版本返回json配置
- hdu 2819 Swap(二分匹配+记录路径,好题)
- 【mysql的设计与优化专题(4)】表的垂直拆分和水平拆分
- 黑马程序员:3分钟带你读懂C/C++学习路线
- Rxjava源码(三)-----线程控制Scheduler
- [HDU 5475] An easy problem (线段树)
- oracle数据导出提示EAP-00091解决办法
- slave_exec_mode对slave影响
- NSArray 快速求总和 最大值 ,最小值 平均值
- 开始csdn
- director.js 传递多个参数
- 常用的获取宽高方法
- 移动应用界面设计的尺寸设置及规范