RxJava2的Observable变种之线程切换

RxJava的线程切换实质就是把不同的处理事务交由不同的线程去进行处理。代码流程看起来热仍然是像Observable.create(observableOnSubscribe).subscribe(observer)这种基本格式。那么线程切换流程在源码上是怎么做到的呢?另外,多个subscribeOn对应不同线程模型时,是都生效还是只对第一个线程有效,以及observeOn对应不同线程模型时,又是否各自在对应的线程生效,接下来,我们在分析源码并简化各步骤中给出答案:

Observable
        .create(new ObservableOnSubscribe<String>() {

            @Override
            public void subscribe(ObservableEmitter<String> observableEmitter) throws Exception {
                observableEmitter.onNext("hello world");
                Log.d("RxJava2", "This msg from work thread :" + Thread.currentThread().getName());
            }
        })
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new io.reactivex.Observer<String>() {
            @Override
            public void onSubscribe(Disposable disposable) {

            }

            @Override
            public void onNext(String s) {
                Log.d("RXJava2", "welcome: " + s);
                Log.d("RxJava2", "This msg from work thread :" + Thread.currentThread().getName());
            }

            @Override
            public void onError(Throwable throwable) {

            }

            @Override
            public void onComplete() {

            }
        });

step1 这一步上文已经分析过了,既返回new ObservableCreate(source)

Observable
        .create(new ObservableOnSubscribe<String>() {

            @Override
            public void subscribe(ObservableEmitter<String> observableEmitter) throws Exception {
                observableEmitter.onNext("hello world");
                Log.d("RxJava2", "This msg from work thread :" + Thread.currentThread().getName());
            }
        })

step2 在step1的结果上,调用

new ObservableCreate(source).subscribeOn(Schedulers.io()

那么返回ObservableSubscribeOn的实例,这里this为step1的结果ObservableCreate实例。

new ObservableSubscribeOn(this, scheduler)

ObservableSubscribeOn继承AbstractObservableWithUpstream,而AbstractObservableWithUpstream继承Observable,因此,正如上文所说的,都为Observable的变种(具体子类实现)。既然是继承关系,那么主要就在于subscribeActual方法,从上文知道,所有进行订阅之后,都会走到具体Observable实例的subscribeActual方法中,这里在后面步骤中再具体分析subscribeActual方法;

step3 在step2的结果下继续执行:

new ObservableSubscribeOn(this, scheduler)
      .observeOn(AndroidSchedulers.mainThread())

那么返回的结果为:

new ObservableObserveOn(this, scheduler, delayError, bufferSize)

其中this为ObservableSubscribeOn实例,同样deObservableObserveOn继承AbstractObservableWithUpstream,如step2分析,同样在订阅的过程中会走到subscribeActual方法。这里在后面步骤中分析。

step4 在step3的结果下继续执行,则如下代码所示:

new ObservableObserveOn(this, scheduler, delayError, bufferSize)
    .subscribe(new io.reactivex.Observer<String>() {
            @Override
            public void onSubscribe(Disposable disposable) {

            }

            @Override
            public void onNext(String s) {
                Log.d("RXJava2", "welcome: " + s);
                Log.d("RxJava2", "This msg from work thread :" + Thread.currentThread().getName());
            }

            @Override
            public void onError(Throwable throwable) {

            }

            @Override
            public void onComplete() {

            }
        });

那么执行这一步之后,既进行了订阅之后,我们找到ObservableObserveOn的subscribe方法,由继承关系,实际还是走到父类Observable的subscribe方法中,同上文,如下:

public final void subscribe(Observer<? super T> observer) {
    ObjectHelper.requireNonNull(observer, "observer is null");

    try {
        observer = RxJavaPlugins.onSubscribe(this, observer);
        ObjectHelper.requireNonNull(observer, "Plugin returned null Observer");
        this.subscribeActual(observer);
    } catch (NullPointerException var4) {
        throw var4;
    } catch (Throwable var5) {
        Exceptions.throwIfFatal(var5);
        RxJavaPlugins.onError(var5);
        NullPointerException npe = new NullPointerException("Actually not, but can't throw other exceptions due to RS");
        npe.initCause(var5);
        throw npe;
    }
}

这时走到subscribeActual方法中,subscribeActual是个抽象方法,具体在子类中实现,这里子类为ObservableObserveOn,进入ObservableObserveOn的子类的subscribeActual方法中,如下:

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

}

我们看到,又调用一个形如this.source.subscribe(observer)的语句,这里的source是什么呢,我们可以套observable.subscribe(observer),这里的source肯定是Observable实例,source是在ObservableObserveOn的构造函数赋值的,而ObservableObserveOn在step3中进行初始化,即,这里的this我们在上面已经分析了,实际就是上一个Observable,即ObservableSubscribeOn。

new ObservableObserveOn(this, scheduler, delayError, bufferSize)

从这里我们可以知道,这里就是类似装饰着模式,装饰者模式的作用就是动态的将责任附加到对象上,提供了比继承更加弹性的替代方案,通过组合的方式实现。

回到这一步来,现在进行到

this.source.subscribe(new ObservableObserveOn.ObserveOnObserver(observer, w, this.delayError, this.bufferSize));

通过上面分析,实际走到ObservableSubscribeOn的subscribe方法中,注意,这里的Observer也进行了一层包装,一开始在订阅的时候,是最简单的observer,而到这里的时候已经进行了一层封装,如下:

new ObservableObserveOn.ObserveOnObserver(observer, w, this.delayError, this.bufferSize)

为ObservableObserveOn.ObserveOnObserver实例,实际上ObserveOnObserver实现了Observer接口。也就是说,Observable从上往下进行了装饰者模式组合封装,而Observer从下往上进行了装饰者模式组合封装,当subscribe的时候,从Observable的最外层开始进行订阅,然后一层层进行subscribeActual的时候,又一层层的组合封装了observer,到达observable最基层的时候,发射器开始发射拿着最外层的observer开始进行一层层的揭开发送事件,最后就到了observer最基层。这部分具体会在下面以图文的形式展开。

现在,就走到ObservableSubscribeOn的subscribeActual方法, 如下:

public void subscribeActual(Observer<? super T> s) {
    ObservableSubscribeOn.SubscribeOnObserver<T> parent = new ObservableSubscribeOn.SubscribeOnObserver(s);
    s.onSubscribe(parent);
    parent.setDisposable(this.scheduler.scheduleDirect(new ObservableSubscribeOn.SubscribeTask(parent)));
}

subscribeActual看起来没有直接调用形如this.source.subscribe(observer)语句,但肯定有相关的。

首先和上面分析的一样,对observer入参进行了一层组合封装,为SubscribeOnObserver实例,然后调用parent.setDisposable方法,主要看

this.scheduler.scheduleDirect(new ObservableSubscribeOn.SubscribeTask(parent));

根据例子,scheduler即为例子中的Schedulers.io(), 即为IoScheduler实例,进入scheduleDirect方法,该方法在父类Scheduler中,会执行如下方法

public Disposable scheduleDirect(@NonNull Runnable run, long delay, @NonNull TimeUnit unit) {
    Scheduler.Worker w = this.createWorker();
    Runnable decoratedRun = RxJavaPlugins.onSchedule(run);
    Scheduler.DisposeTask task = new Scheduler.DisposeTask(decoratedRun, w);
    w.schedule(task, delay, unit);
    return task;
}

这里run即为ObservableSubscribeOn.SubscribeTask实例,调用this.createWorker()进入到IoScheduler的具体方法实现中去

public Worker createWorker() {
    return new IoScheduler.EventLoopWorker((IoScheduler.CachedWorkerPool)this.pool.get());
}

接着执行w.schedule方法,这里的w即为上面的EventLoopWorker实例,方法中代码如下:

public Disposable schedule(@NonNull Runnable action, long delayTime, @NonNull TimeUnit unit) {
    return (Disposable)(this.disposed ? EmptyDisposable.INSTANCE : this.poolWorker.scheduleActual(action, delayTime, unit, this.timed));
}

this.poolWorker.scheduleActual的实现如下:

public ScheduledRunnable scheduleActual(Runnable run, long delayTime, @NonNull TimeUnit unit, @Nullable DisposableContainer parent) {
    Runnable decoratedRun = RxJavaPlugins.onSchedule(run);
    ScheduledRunnable sr = new ScheduledRunnable(decoratedRun, parent);
    if (parent != null && !parent.add(sr)) {
        return sr;
    } else {
        try {
            Object f;
            if (delayTime <= 0L) {
                f = this.executor.submit(sr);
            } else {
                f = this.executor.schedule(sr, delayTime, unit);
            }

            sr.setFuture((Future)f);
        } catch (RejectedExecutionException var10) {
            if (parent != null) {
                parent.remove(sr);
            }

            RxJavaPlugins.onError(var10);
        }

        return sr;
    }
}

最后执行了ScheduledRunnable,而ScheduledRunnable的run方法中执行了Scheduler.DisposeTask实例的run方法,而DisposeTask的run方法又执行了new ObservableSubscribeOn.SubscribeTask实例的run方法,其实现如下:

ObservableSubscribeOn.this.source.subscribe(this.parent);

是不是饶了一大圈,又回到了我们熟悉的this.source.subscribe(observer),这也验证了我们猜测的,回顾一下刚才一路分析下来的,例子中调用了subscribeOn方法,那么在subscribe的过程中,会创建相应的线程,那么谁会在这个线程做些操作呢?

我们继续上面分析到this.source.subscribe(observer),这里ObservableSubscribeOn.this.source即为例子中ObservableCreate,这时就进入到ObservableCreate的subscribeActual方法,然后执行this.source.subscribe(observer),这里的source即为例子中ObservableOnSubscribe的实例,终于,我们要在ObservableOnSubscribe执行subscribe方法了,这里是最基层的,那么执行subscribe的方法是在哪个线程执行的呢?还记得我们前面分析的创建了线程并在线程中执行了run方法,而run方法里面最终就进入到最基层的ObservableOnSubscribe的suscribe方法中来。因此,我们通过上面的分析,可以得出,无论例子中进行了多少次subscribeOn方法,最终执行的subscrbe方法是运行在第一次subscribeOn指定的线程中。

step5 进到到ObservableOnSubscribe的subscrbe方法之后,就要开始通过发射器发射事件了。而我们这里的发射就是组合了observer一层层封装而来。我们再一步步分析this.source.subcribe(observer)已经分析了,那么发射器的发射流程如下所示:

observableEmitter.onNext("hello world") ---> ObservableSubscribeOn.SubscribeOnObserver.onNext("hello world")---> ObservableObserveOn.ObserveOnObserver.onNext("hello word")--->new Observer("hello word")

这里分析下调用ObservableObserveOn.ObserveOnObserver.onNext("hello word")方法之后,是怎么切换到main线程的。ObserveOnObserver的onNext方法如下:

public void onNext(T t) {
    if (!this.done) {
        if (this.sourceMode != 2) {
            this.queue.offer(t);
        }

        this.schedule();
    }
}

void schedule() {
    if (this.getAndIncrement() == 0) {
        this.worker.schedule(this);
    }

}

既进入到worker的schedule方法中,例子中对应的Scheduler为HandlerScheduler,那么对应的worker为HandlerWork,同样的,进入schedule方法中,如下:

@Override
public Disposable schedule(Runnable run, long delay, TimeUnit unit) {
    if (run == null) throw new NullPointerException("run == null");
    if (unit == null) throw new NullPointerException("unit == null");

    if (disposed) {
        return Disposables.disposed();
    }

    run = RxJavaPlugins.onSchedule(run);

    ScheduledRunnable scheduled = new ScheduledRunnable(handler, run);

    Message message = Message.obtain(handler, scheduled);
    message.obj = this; // Used as token for batch disposal of this worker's runnables.

    handler.sendMessageDelayed(message, unit.toMillis(delay));

    // Re-check disposed state for removing in case we were racing a call to dispose().
    if (disposed) {
        handler.removeCallbacks(scheduled);
        return Disposables.disposed();
    }

    return scheduled;
}

既然是线程执行方法,找到某个run方法,这个run方法为ObserveOnObserver本身

。最终在HandlerScheduler中通过消息机制把执行ObserveOnObserver的run方法,

public void run() {
    if (this.outputFused) {
        this.drainFused();
    } else {
        this.drainNormal();
    }

}

最终就会执行observer.onNext()。

上面即为RxJava线程的切换过程,不管怎么变换,只要认准observable.subscribe(observer)即可,万变不离其宗。最后补充两张图,可以形象说明这种流式过程是怎么进行的:

18582563-20899ba99f1cedfe
image
18582563-cc5f8cdcd05b1751
image
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值