RxJava线程切换原理

样本代码

以此示例为基础结合源码来了解Rxjava线程切换的原理

Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                System.out.println("被观察者线程:"+Thread.currentThread().getName());
                emitter.onNext("123");
            }
        }).subscribeOn(Schedulers.newThread())
          .observeOn(AndroidSchedulers.mainThread())
          .subscribe(new Observer<String>() {
            @Override
            public void onSubscribe(Disposable d) {
            }

            @Override
            public void onNext(String s) {
                System.out.println("观察者线程:"+Thread.currentThread().getName());
            }

            @Override
            public void onError(Throwable e) {
            }

            @Override
            public void onComplete() {
            }
        });

 

方法执行流程

一.首先来看Observable.create干了什么

1.跟代码进入Observable.java文件中

public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
        ObjectHelper.requireNonNull(source, "source is null");
        return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));
    }

requireNonNull是用来校验传入的ObservableOnSubscribe匿名内部类source是否为null

 

2.我们来看onAssembly干了什么

public static <T> Observable<T> onAssembly(@NonNull Observable<T> source) {
        Function<? super Observable, ? extends Observable> f = onObservableAssembly;
        if (f != null) {
            return apply(f, source);
        }
        return source;
    }

onObservableAssembly是一个Function  若不为空则在source对象返回前对source对象进行处理 可通过RxjavaPlugins设置

默认为null所以示例中会直接返回传入的source对象也就是onAssembly中传入的对象

 

3.onAssembly中传入的对象为new ObservableCreate<T>(source)跟进代码

进入ObservableCreate.java文件

注:subscribeActual方法后续调用后续说明

public final class ObservableCreate<T> extends Observable<T> {
    final ObservableOnSubscribe<T> source;

    public ObservableCreate(ObservableOnSubscribe<T> source) {
        this.source = source;
    }

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

        try {
            source.subscribe(parent);
        } catch (Throwable ex) {
            Exceptions.throwIfFatal(ex);
            parent.onError(ex);
        }
    }

这里可以看到new ObservableCreate<T>(source)创建了一个继承自Observable对象的实例并将 source即Observable.create创建的匿名内部类赋值到该对象的成员变量

因此Observable.create方法做的事情就是获得一个携带传入对象的 ObservableCreate对象

传入对象继承自ObservableOnSubscribe     返回对象继承自Observable

 

 

二.继续看一步骤返回的对象调用subscribeOn干了什么

Scheduler是什么

(以Schedulers.newThread()为例)

@NonNull
    public static Scheduler newThread() {
        return RxJavaPlugins.onNewThreadScheduler(NEW_THREAD);
    }

onNewThreadScheduler作用与1.1中的作用同理这里不再说明本例中返回对象为NEW_THREAD

看下NEW_THREAD的初始化

NEW_THREAD = RxJavaPlugins.initNewThreadScheduler(new NewThreadTask());

继续跟NewThreadTask

static final class NewThreadTask implements Callable<Scheduler> {
        @Override
        public Scheduler call() throws Exception {
            return NewThreadHolder.DEFAULT;
        }
    }

继续

static final class NewThreadHolder {
        static final Scheduler DEFAULT = new NewThreadScheduler();
    }

继续

public NewThreadScheduler() {
        this(THREAD_FACTORY);
    }

    public NewThreadScheduler(ThreadFactory threadFactory) {
        this.threadFactory = threadFactory;
    }

    @NonNull
    @Override
    public Worker createWorker() {
        return new NewThreadWorker(threadFactory);
    }

这里创建了一个Scheduler的子类并初始化了threadFactory

我们看下createWorker中做了什么

一路跟代码可以找到

public static ScheduledExecutorService create(ThreadFactory factory) {
        final ScheduledExecutorService exec = Executors.newScheduledThreadPool(1, factory);
        tryPutIntoPool(PURGE_ENABLED, exec);
        return exec;
    }

可以看到这里创建了一个核心先程序为1的线程池

 

进入正题

1.跟进代码 看以看到 方法执行流程和一.1差不多 多了一个Scheduler入参 返回对象的初始化也不同

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

与1.1中相同方法不再赘述

this为当前调用者的实例也就是 一.1步骤返回的对象

看下不同的地方new ObservableSubscribeOn<T>(this, scheduler)干了什么

 

2.跟代码进入ObservableSubscribeOn.java

  注:subscribeActual方法后续调用后续说明

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> observer) {
        final SubscribeOnObserver<T> parent = new SubscribeOnObserver<T>(observer);

        observer.onSubscribe(parent);

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

这里创建了一个继承自AbstractObservableWithUpstream的类

这里做了两件事

1.将source传递给父类构造

2.将变量scheduler赋值 

那父类AbstractObservableWithUpstream是什么呢

abstract class AbstractObservableWithUpstream<T, U> extends Observable<U> implements HasUpstreamObservableSource<T> {

    /** The source consumable Observable. */
    protected final ObservableSource<T> source;

    /**
     * Constructs the ObservableSource with the given consumable.
     * @param source the consumable Observable
     */
    AbstractObservableWithUpstream(ObservableSource<T> source) {
        this.source = source;
    }

可以看到父类构造中将source赋值给成员变量

 

3.回到二.1我们可以知道

subscribeOn干了什么 

通过

初始化并返回了一个携带有 scheduler(线程池)source(步骤一.返回对象)的ObservableSubscribeOn对象

 

 

三.继续看二步骤返回的对象调用observeOn干了什么

1.跟代码进入方法

public final Observable<T> observeOn(Scheduler scheduler) {
        return observeOn(scheduler, false, bufferSize());
    }

继续跟

public final Observable<T> observeOn(Scheduler scheduler, boolean delayError, int bufferSize) {
        ObjectHelper.requireNonNull(scheduler, "scheduler is null");
        ObjectHelper.verifyPositive(bufferSize, "bufferSize");
        return RxJavaPlugins.onAssembly(new ObservableObserveOn<T>(this, scheduler, delayError, bufferSize));
    }

这里的this为调用者步骤二中返回的对象

这里多了两个入参 delayError 和 bufferSize 采用的默认值不做关注

其它校验方法不再赘述我们直接看主要的new ObservableObserveOn<T>(this, scheduler, delayError, bufferSize));做了什么

 

2.跟进代码

注: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));
        }
    }

和二中一样这里将成员变量赋值后同样调用了父类构造   在父类构造中依然将source赋值

 

3.回到三.1我们可以知道

observeOn干了什么 

初始化并返回了一个携带有 scheduler(线程池)source(步骤二返回的对象)的ObservableObserveOn对象

 

 

------------------------------------------------------------------------------------------------------------------------------------------------------------

到这里我们回忆下前三步干了什么

 

第一步:返回一个携带匿名对象的Observable子类对象

第二步:返回一个携带scheduler对象和“第一步”对象的Observable子类对象

第三部:返回一个携带scheduler对象和“第二步”对象的Observable子类对象

 

四.继续看三步骤返回的对象调用subscribe方法干了什么

subscribe方法传入一个Observer(观察者)对象

 

1、跟进subscribe方法 进入Observable.java中

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");

            subscribeActual(observer);
        } catch (NullPointerException e) { // NOPMD
            throw e;
        } catch (Throwable e) {
            Exceptions.throwIfFatal(e);
            // can't call onError because no way to know if a Disposable has been set or not
            // can't call onSubscribe because the call might have set a Subscription already
            RxJavaPlugins.onError(e);

            NullPointerException npe = new NullPointerException("Actually not, but can't throw other exceptions due to RS");
            npe.initCause(e);
            throw npe;
        }
    }

验证校验方法不再赘述 

 

2.继续跟进subscribeActual方法

protected abstract void subscribeActual(Observer<? super T> observer);

可以看到这是一个抽象方法 那1.中的subscribeActual实际调用的是哪个方法呢

是否还记得三步骤中返回的Obserberable子类对象也就是subscribe方法的调用者 这里调用的是自身的subscribeActual方法

(一、二、三种标有“注:subscribeActual方法后续调用后续说明”) 这里的subscribeActual调用的是三步骤中的同时传入一个

Observer对象。图示

                          

 

3.我们来看3步骤中的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));
        }
    }

方法接收一个Observer对象

进入方法有一个判断   if (scheduler instanceof TrampolineScheduler)    TrampolineScheduler的作用为会将任务放置到任务队列中待上一个任务完成后执行即不进行线程切换

 

进入else 通过scheduler.createWorker创建了一个线程池或线程

我们先看source.subscribe的入参new ObserveOnObserver是什么

static final class ObserveOnObserver<T> extends BasicIntQueueDisposable<T>
    implements Observer<T>, Runnable 

这里我们可以理解为new ObserveOnObserver创建了一个 实现了Observer接口和Runnable接口并携带“线程池”的类

 

然后执行source.subscribe

source还记得是什么吗 三对象的source为二中返回的对象 

所以 source.subscribe 调用的是二步骤中的subscribe方法

 

图示

我们看看它做了什么

@Override
    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");

            subscribeActual(observer);
        } catch (NullPointerException e) { // NOPMD
            throw e;
        } catch (Throwable e) {
            Exceptions.throwIfFatal(e);
            // can't call onError because no way to know if a Disposable has been set or not
            // can't call onSubscribe because the call might have set a Subscription already
            RxJavaPlugins.onError(e);

            NullPointerException npe = new NullPointerException("Actually not, but can't throw other exceptions due to RS");
            npe.initCause(e);
            throw npe;
        }
    }

可以看到subscribe经过一系列判断后调用的是自身的subscribeActual方法

 

4.我们继续看第二个步骤返回的对象中subscribeActual方法干了什么

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

        observer.onSubscribe(parent);

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

这里首先创建了一个SubscribeOnObserver对象我们看下是什么

final class SubscribeOnObserver<T> extends AtomicReference<Disposable> implements Observer<T>, Disposable

这里创建了一个实现了Observer和Disposable接口并携带observer对象的SubscribeOnObserver

返回subscribeActual方法中

 

下面直接调用了observer.onSubscribe(parent);方法

observer是什么  是步骤四.3中传入的Observer实现类

所以此处调用的是步骤四.3中传入的Observer实现类的onSubscribe方法

我们看看它做了什么

 @Override
        public void onSubscribe(Disposable d) {
            if (DisposableHelper.validate(this.upstream, d)) {
                this.upstream = d;
                if (d instanceof QueueDisposable) {
                    @SuppressWarnings("unchecked")
                    QueueDisposable<T> qd = (QueueDisposable<T>) d;

                    int m = qd.requestFusion(QueueDisposable.ANY | QueueDisposable.BOUNDARY);

                    if (m == QueueDisposable.SYNC) {
                        sourceMode = m;
                        queue = qd;
                        done = true;
                        downstream.onSubscribe(this);
                        schedule();
                        return;
                    }
                    if (m == QueueDisposable.ASYNC) {
                        sourceMode = m;
                        queue = qd;
                        downstream.onSubscribe(this);
                        return;
                    }
                }

                queue = new SpscLinkedArrayQueue<T>(bufferSize);

                downstream.onSubscribe(this);
            }
        }

这里进行了同步异步判断并最终调用了downstream.onSubscribe(this);

 

我们切回到subscribeActual方法中继续向下

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

从内向外看 首先看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);
        }
    }

这里创建了一个实现Runnable接口的类并携带传入的Observer实现类

且回到subscribeActual方法

继续看scheduler.scheduleDirect

scheduler.scheduleDirect直接将Runnable放入线程池中执行也就是执行了 run方法

run中执行了source.subscribe 还记得此时的source是什么吗

source为第一步

返回的对象

这里调用source.subscribe方法即调用了上图中的subscribe方法(调用流程同上)并将parent对象传入方法中

这里可以知道subscribe在哪个线程执行是和.subscribeOn传入的线程有关的

 

5.我们继续看.subsribe方法中做的事情

示例代码中执行了emitter.onNext方法

emitter为4步骤中创建的SubscribeOnObserver对象

调用了其中的onNext方法

我们看该方法做了什么

@Override
        public void onNext(T t) {
            downstream.onNext(t);
        }

这里onNext直接调用了downstream.onNext方法

downstream为步骤3中传入的observer对象 我们继续看步骤3中传入的observer对象的onNext方法

@Override
        public void onNext(T t) {
            if (done) {
                return;
            }

            if (sourceMode != QueueDisposable.ASYNC) {
                queue.offer(t);
            }
            schedule();
        }

两个if判断用于判断同步异步执行  详情在该方法上面的onSubscribe方法可以看到

sourceMode为空所以向队列中插入传递过来的参数t

这里我们直接看schedule();方法

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

这个判断用于防止多次执行

然后调用worker.schedule(this);运行当前对象中的run方法

@Override
        public void run() {
            if (outputFused) {
                drainFused();
            } else {
                drainNormal();
            }
        }

run方法中outputFused为默认值false

所以执行drainNormal方法

void drainNormal() {
            int missed = 1;

            final SimpleQueue<T> q = queue;
            final Observer<? super T> a = downstream;

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

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

                    try {
                        v = q.poll();
                    } catch (Throwable ex) {
                        Exceptions.throwIfFatal(ex);
                        disposed = true;
                        upstream.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;
                }
            }
        }

方法中经过一系列判断 从队列中取出刚刚存入的值t 最终执行了a.onNext(t)此时的a为

所以会调用上图中的OnNext方法

 

run方法的执行取决于worker线程 所以onNext方法在哪个线程执行将由

.obserbeOn传入的参数决定

 

回顾

实线为同步调用  虚线为线程切换

A*是被观察者的实现类   B*是观察者的实现类  

 

1.首先create方法创建Observable实现类并一路传递封装

2.到达A3.subscribe方法时会传入一个(Observer)观察者实现类 并一路回调subscribe方法

3.到达A1的subscribe方法时(确切的是subscribeActua方法)时会调用B3(经过封装的Obserber实现类)的onSubscribe方法

   一路回调至B1的onSubscribe通知完成观察者的注册

4.之后A1的subscribeActua方法通过指定线程调用传入的事件即ObservableOnSubscribe的subscribe方法

5.subscribe方法通过指定线程执行B4的onNext方法 并逐级调用观察者的onNext方法完成

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值