Rxjava基本原理解析(五)

    上一篇分享了线程切换的一个操作符,今天我们继续分析线程切换的另一个操作符observeOn以及其源码设计。

    observeOn操作符用于切换observer的线程:

Observable.create((ObservableOnSubscribe<String>) e -> {
            e.onNext("dawson"); 
        })
        .observeOn(Schedulers.newThread())
        .subscribe(s -> System.out.println("onnext value: " + s));

    observeOn操作符需要传一个scheduler用于指定线程,并创建一个被观察者:ObservableObserveOn和一个观察者ObserveOnObserver。 ObservableObserveOn的source为上一个observable,最重的是其ObserveOnObserver,线程切换发生在该对象中。首先我们看看其subscribeActual的源码:

@Override
protected void subscribeActual(Observer<? super T> observer) {
    if (scheduler instanceof TrampolineScheduler) {
        source.subscribe(observer);
    } else {
        Scheduler.Worker w = scheduler.createWorker();
        source.subscribe(new ObserveOnObserver<T>(observer, w, delayError, bufferSize));
    }
}

    根据指定的scheduler获取其worker(上一篇文章已经分析了scheduler和worker的基本工作原理),并将worker和下游的observer传入到创建的ObserveOnObserver对象。下面看看ObserveOnObserver对象的onNext方法:

@Override
public void onNext(T t) {
    if (done) {
        return;
    }
    if (sourceMode != QueueDisposable.ASYNC) {
        queue.offer(t);
    }
    schedule();
}

    该方法不是直接调用下游的observer.onNext方法,而是将事件加入队列中,然后调用schedule()方法。Schedule方法会调用worker.schedule(this),然后回调run()方法,最后调用drainNormal()方法。而worker内部会使用指定的线程调用,那么drainNormal()即会在指定的新线程中执行。我们看看drainNormal()的部分源码:

void drainNormal() {
    int missed = 1;
    final SimpleQueue<T> q = queue;
    final Observer<? super T> a = actual;
    
    for (;;) {
        //...
        for (;;) {
            boolean d = done;
            T v;
            try {
                v = q.poll();
            } catch (Throwable ex) {
               //...
                return;
            } 
           //... 
            a.onNext(v);
        }
    //...
    }
}

    核心代码就是取出队列中的事件,然后调用下游的observer.onNext()方法将事件传递下去。由于该方法是在worker指定的新线程中执行,因此后面的observer处理逻辑都会在新线程执行,实现线程切换。在上一篇最后的流程图中加入observeOn,结合图进行分析和理解:

流程

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值