RxJava线程切换源码分析

参考文章

在分析线程切换源码之前有必要分析订阅流程。

        Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                e.onNext(100);
                e.onNext(200);
                e.onComplete();
            }
        }).subscribe(new Observer<Integer>() {
            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onNext(Integer integer) {
                Log.e("shenkai", "onNext:" + integer);
            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onComplete() {
                Log.e("shenkai", "onComplete: ");
            }
        });

先分析创建流程,Observable#create是把我们传进去的ObservableOnSubscribe对象包装成ObservableCreate对象并返回。如下图:
在这里插入图片描述
再看调用subscribe方法,subscribe中调用了subscribeActual,它是个抽象方法,此时的子类是ObservableCreate对象,看ObservableCreate#subscribeActual:

    protected void subscribeActual(Observer<? super T> observer) {
        CreateEmitter<T> parent = new CreateEmitter<T>(observer);
        observer.onSubscribe(parent);
        source.subscribe(parent);
    }

第一步把观察者Observer包装成CreateEmitter对象,第二步调用observer.onSubscribe(parent);并把CreateEmitter对象传进去,第三部的source是我们创建的ObservableOnSubscribe对象,CreateEmitter是ObservableEmitter的实现类,当我们调用emitter.onNext时会调用observer的onNext,具体就不贴代码了。

    static final class CreateEmitter<T>
    extends AtomicReference<Disposable>
    implements ObservableEmitter<T>, Disposable {

接下来分析线程切换,先分析subscribeOn方法

        new Thread() {
            @Override
            public void run() {
                Observable.create(new ObservableOnSubscribe<Integer>() {
                    @Override
                    public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                        Log.e(TAG, "subscribe: " + Thread.currentThread());
                        e.onNext(100);
                        e.onNext(200);
                        e.onComplete();
                    }
                })
                        .subscribeOn(Schedulers.io())
                        .subscribe(new Observer<Integer>() {
                            @Override
                            public void onSubscribe(Disposable d) {
                                Log.e(TAG, "onSubscribe: " + Thread.currentThread());
                            }

                            @Override
                            public void onNext(Integer integer) {
                                Log.e(TAG, "onNext: " + Thread.currentThread());
                                Log.e(TAG, "onNext:" + integer);
                            }

                            @Override
                            public void onError(Throwable e) {

                            }

                            @Override
                            public void onComplete() {
                                Log.e(TAG, "onComplete: ");
                            }
                        });
            }
        }.start();

Observable#subscribeOn是把调用subscribeOn方法的被观察者包装成ObservableSubscribeOn,这里调用subscribeOn的被观察者是ObservableCreate对象。

    public final Observable<T> subscribeOn(Scheduler scheduler) {
        ObjectHelper.requireNonNull(scheduler, "scheduler is null");
        return RxJavaPlugins.onAssembly(new ObservableSubscribeOn<T>(this, scheduler));
    }

在这里插入图片描述
从订阅流程可知Observable#subscribe会调用子类的subscribeActual,我们看看ObservableSubscribeOn#subscribeActual方法吧:

    @Override
    public void subscribeActual(final Observer<? super T> s) {
        final SubscribeOnObserver<T> parent = new SubscribeOnObserver<T>(s);

        s.onSubscribe(parent);

        parent.setDisposable(scheduler.scheduleDirect(new SubscribeTask(parent)));
    }

第一步是把我们传进去的观察者包装成SubscribeOnObserver,第二步调用观察者的onSubscribe方法,第三步首先是把SubscribeOnObserver包装成SubscribeTask对象,

    final class SubscribeTask implements Runnable {
        private final SubscribeOnObserver<T> parent;

        SubscribeTask(SubscribeOnObserver<T> parent) {
            this.parent = parent;
        }

        @Override
        public void run() {
            source.subscribe(parent);
        }
    }

这里的source是ObservableCreate对象。
接着看scheduler.scheduleDirect,

    public Disposable scheduleDirect(@NonNull Runnable run, long delay, @NonNull TimeUnit unit) {
        final Worker w = createWorker();

        final Runnable decoratedRun = RxJavaPlugins.onSchedule(run);
		//把任务和worker包装成DisposeTask
        DisposeTask task = new DisposeTask(decoratedRun, w);
		//把DisposeTask交给worker调度
        w.schedule(task, delay, unit);

        return task;
    }

createWorker是个抽象方法,这里的子类实现是
IoScheduler#createWorker

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

接着看EventLoopWorker#schedule:

        public Disposable schedule(@NonNull Runnable action, long delayTime, @NonNull TimeUnit unit) {
            if (tasks.isDisposed()) {
                // don't schedule, we are unsubscribed
                return EmptyDisposable.INSTANCE;
            }

            return threadWorker.scheduleActual(action, delayTime, unit, tasks);
        }

NewThreadWorker#scheduleActual

public ScheduledRunnable scheduleActual(final Runnable run, long delayTime, @NonNull TimeUnit unit, @Nullable DisposableContainer parent) {
    Runnable decoratedRun = RxJavaPlugins.onSchedule(run);

    ScheduledRunnable sr = new ScheduledRunnable(decoratedRun, parent);

    if (parent != null) {
        if (!parent.add(sr)) {
            return sr;
        }
    }

    Future<?> f;
    try {
        if (delayTime <= 0) {
            f = executor.submit((Callable<Object>)sr);
        } else {
            f = executor.schedule((Callable<Object>)sr, delayTime, unit);
        }
        sr.setFuture(f);
    } catch (RejectedExecutionException ex) {
        if (parent != null) {
            parent.remove(sr);
        }
        RxJavaPlugins.onError(ex);
    }

    return sr;
}

实际上就是把任务交给线程池执行,也就是说SubscribeTask#run方法中的代码都会在线程池执行。也就是发射事件的代码和观察者中执行的代码都在线程池中执行了,这样就完成了线程切换。subscribeOn多次调用只有第一次有效,这是为什么呢?

.subscribeOn(Schedulers.io())
.subscribeOn(Schedulers.computation())
.subscribeOn(AndroidSchedulers.mainThread())

因为每调用一次subscribeOn就把上游的Observable包装成ObservableSubscribeOn对象,来看看这个对象的创建

public final class ObservableSubscribeOn<T> extends AbstractObservableWithUpstream<T, T> {
    final Scheduler scheduler;

    public ObservableSubscribeOn(ObservableSource<T> source, Scheduler scheduler) {
        super(source);
        this.scheduler = scheduler;
    }
    
        @Override
    public void subscribeActual(final Observer<? super T> s) {
        final SubscribeOnObserver<T> parent = new SubscribeOnObserver<T>(s);

        s.onSubscribe(parent);

        parent.setDisposable(scheduler.scheduleDirect(new SubscribeTask(parent)));
    }
    ...
}

在这里插入图片描述
scheduler.scheduleDirect(new SubscribeTask(parent))所做的事情是指定上一层Observable#subscribe执行在本层指定的线程。直到顶层Observable也就是ObservableCreate#subscribe被执行,它执行所在的线程当然就是离他最近的subscribeOn,本例是subscribeOn(Schedulers.io())。
总结:subscribeOn多次调用只有第一次有效原因看上图第三次调用会执行第二层被包装被观察者的subscribe方法,第二层又会调用第一层被包装的subscribe方法,通过这样层层调用最终我们传递进去的ObservableOnSubscribe的subscribe方法执行的线程就是离他最近调用的subscribeOn方法参数所在的线程。

Observable#observeOn
        new Thread() {
            @Override
            public void run() {
                Log.e("TAG", "当前线程环境:" + Thread.currentThread().getName());
                Observable.create(new ObservableOnSubscribe<String>() {
                    @Override
                    public void subscribe(ObservableEmitter<String> e) throws Exception {
                        e.onNext("A");
                        e.onComplete();
                    }
                })
//                .subscribeOn(Schedulers.io())
                        .observeOn(AndroidSchedulers.mainThread())
                        .subscribe(new Observer<String>() {
                            @Override
                            public void onSubscribe(Disposable d) {
                                Log.e("TAG", "onSubscribe线程环境:" + Thread.currentThread().getName());
                            }

                            @Override
                            public void onNext(String s) {
                                Log.e("TAG", "onNext线程环境:" + Thread.currentThread().getName());
                            }

                            @Override
                            public void onError(Throwable e) {

                            }

                            @Override
                            public void onComplete() {

                            }
                        });
            }
        }.start();

Observable#observeOn是把上游Observable和scheduler包装为ObservableObserveOn对象并返回。

new ObservableObserveOn<T>(this, scheduler, delayError, bufferSize)

看看ObservableObserveOn的构造方法和subscribeActual方法。

public final class ObservableObserveOn<T> extends AbstractObservableWithUpstream<T, T> {
    final Scheduler scheduler;
    final boolean delayError;
    final int bufferSize;
    public ObservableObserveOn(ObservableSource<T> source, Scheduler scheduler, boolean delayError, int bufferSize) {
        super(source);
        this.scheduler = scheduler;
        this.delayError = delayError;
        this.bufferSize = bufferSize;
    }

    @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));
        }
    }
   ...
 }

在subscribeActual方法else语句中调用上游被观察者的subscribe方法,注意此时并没有切换线程,也就是说Observable#observeOn并不会改变上游的执行线程。接着把观察者包装成ObserveOnObserver对象。我们看看ObserveOnObserver对象的onNext方法:

        public void onNext(T t) {
            if (sourceMode != QueueDisposable.ASYNC) {
                queue.offer(t);
            }
            schedule();
        }
        
        void schedule() {
            if (getAndIncrement() == 0) {
                worker.schedule(this);
            }
        }
        
        public void run() {
            if (outputFused) {//默认为false
                drainFused();
            } else {
                drainNormal();
            }
        }
        void drainNormal() {
            int missed = 1;

            final SimpleQueue<T> q = queue;
            final Observer<? super T> a = actual;//被包装的观察者

            for (;;) {
                if (checkTerminated(done, q.isEmpty(), a)) {
                    return;
                }

                for (;;) {
                    boolean d = done;
                    T v;

                    try {
                        v = q.poll();
                    } catch (Throwable ex) {
                        Exceptions.throwIfFatal(ex);
                        s.dispose();
                        q.clear();
                        a.onError(ex);
                        worker.dispose();
                        return;
                    }
                    boolean empty = v == null;

                    if (checkTerminated(d, empty, a)) {
                        return;
                    }

                    if (empty) {
                        break;
                    }

                    a.onNext(v);
                }

                missed = addAndGet(-missed);
                if (missed == 0) {
                    break;
                }
            }
        }

这样就把观察者的onNext方法置于指定的线程中执行了。
简而言之new ObserveOnObserver(observer, w, delayError, bufferSize)这行代码内部实现是w开线程执行observer,每调用一次observerOn都开启指定线程执行下游观察者,这就达到了每次调用observerOn都对下游有效。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值