RxJava执行流程及线程切换

背景

看完记录下来踏实点

用法代码示例

Observable.create(new ObservableOnSubscribe<Integer>() {
                    @Override
                    public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                        Log.d(TAG, "create: " + Thread.currentThread().getName());
                        e.onNext(1);
                        e.onNext(2);
                    }
                })
    			.flatMap(new Function<Integer, ObservableSource<Integer>>() {
                    @Override
                    public ObservableSource<Integer> apply(Integer integer) throws Exception {
                        Log.d(TAG, "flatMap: " + Thread.currentThread().getName());
                        return Observable.just(integer);
                    }
                })
    			.subscribeOn(Schedulers.io())
          .subscribeOn(Schedulers.newThread())
          .observeOn(AndroidSchedulers.mainThread())
          .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.d(TAG, "Consumer: " + Thread.currentThread().getName());
                    }
                });
1、创建Observable引用链

代码从上执行到下,分别会创建Observable的不同子类对象,比如ObservableObserveOn.create()会创建ObservableCreate子类对象;Observable.flatMap()会创建ObservableFlatMap子类对象,代码如下:

// Observable.create()
public static <T> Observable<T> create(ObservableOnSubscribe<T> source) {
    ObjectHelper.requireNonNull(source, "source is null");
    // 返回ObservableCreate,参数是ObservableOnSubscribe
    return RxJavaPlugins.onAssembly(new ObservableCreate<T>(source));
}
// Observable.flatMap()
public final <R> Observable<R> flatMap(Function<? super T, ? extends ObservableSource<? extends R>> mapper,
            boolean delayErrors, int maxConcurrency, int bufferSize) {
    ...
    // 返回ObservableFlatMap,参数是Function
    return RxJavaPlugins.onAssembly(new ObservableFlatMap<T, R>(this, mapper, delayErrors, maxConcurrency, bufferSize));
}

需要注意的是,每个子类对象都会持有其调用者的引用,即source参数,如ObservableFlatMap的构造函数:

public ObservableFlatMap(ObservableSource<T> source,
            Function<? super T, ? extends ObservableSource<? extends U>> mapper,
            boolean delayErrors, int maxConcurrency, int bufferSize) {
    	// source即调用者Observale,如ObservableCreate.flatMap(),source就是ObservableCreate
        super(source);
        ...
    }

因此本例中,生成的对象及其引用链如下(注 —> : 表示后面持有前面):

ObservableOnSubscribe —> ObservableCreate —> ObservableFlatMap —> ObservableSubscribeOn —> ObservableSubscribeOn —> ObservableObserveOn

2、创建Observer引用链

Rxjava分观察者(Observer)和被观察者(Observable),由第一步分析可知,执行订阅(subscribe)之前只会创建引用链,而没有真正执行,真正开始执行是在调用**subscribe()**方法的时候。

订阅后发现最终会调用这个方法subscribe(Observer<? super T> observer),Consumer对象会被包裹为一个Observer(即LambdaObserver)。

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

subscribeActual()是Observable的抽象方法,最终的实现要看Observable子类实现,即调用subscribe()方法的对象,本例是observeOn(AndroidSchedulers.mainThread())。即ObservableObserveOn

public final class ObservableObserveOn<T> extends AbstractObservableWithUpstream<T, T> {
    
    @Override
    protected void subscribeActual(Observer<? super T> observer) {
        if (scheduler instanceof TrampolineScheduler) {
            source.subscribe(observer);
        } else {
            Scheduler.Worker w = scheduler.createWorker();
			// 调用source去执行订阅
            source.subscribe(new ObserveOnObserver<T>(observer, w, delayError, bufferSize));
        }
    }
}

可以看到当开始订阅时,会去先执行上游Observable的订阅方法(Observable.subscribe())传入的是包裹后的Observer,如ObserveOnObserver

因此本例中,Observer引用链如下(注 <— : 表示前面持有后面)

CreateEmitter <— MergeObserver <— SubscribeOnObserver <— SubscribeOnObserver <— ObserveOnObserver <— Observer

4、执行流程

结合前两步,可得如下订阅关系:

在这里插入图片描述

执行流程如下:

在这里插入图片描述

5、线程切换

与普通的Observale不同的是,ObservableSubscribeOnObservableObserveOn可以用来切换线程。

5.1、消费线程
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)));
    }

具体要执行的线程通过参数判断,如Schedulers.io()Schedulers.newThread()AndroidSchedulers.mainThread()等,分别对应IoScheduler(缓存池)NewThreadScheduler(新线程)HandlerScheduler(Handler主线程)

scheduler.scheduleDirect()会根据不同的线程类型创建不同的Worker

public Disposable scheduleDirect(@NonNull Runnable run, long delay, @NonNull TimeUnit unit) {
        // 创建不同的worker
        final Worker w = createWorker();

        final Runnable decoratedRun = RxJavaPlugins.onSchedule(run);

        DisposeTask task = new DisposeTask(decoratedRun, w);
		// 执行
        w.schedule(task, delay, unit);

        return task;
    }

//IoScheduler
	public Worker createWorker() {
        return new EventLoopWorker(pool.get());
    }
//NewThreadScheduler
	public Worker createWorker() {
        return new NewThreadWorker(threadFactory);
    }
//HandlerScheduler
	public Worker createWorker() {
        return new HandlerWorker(handler);
    }

如本例中,执行线程进行了两次切换

.subscribeOn(Schedulers.io())
.subscribeOn(Schedulers.newThread())

注意到scheduler.scheduleDirect(new SubscribeTask(parent))的参数,因此最终会执行到SubscribeTask的run()方法里,可以看到也是执行了source的订阅方法。

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是subscribeOn(Schedulers.io()),会再次切换一次线程,在IoScheduler中执行SubscribeTask的run()方法。因此上游source都在IoScheduler中进行。

小结:

因为调用顺序是从下执行到上,如果连续执行线程切换,只会执行在最上流的切换线程中,下流的切换只是在别的线程中完成了上流的线程切换。

5.2、切换主线程

主线程切换发生在ObservableObserveOn的ObserveOnObserver中

public final class ObservableObserveOn<T> extends AbstractObservableWithUpstream<T, T> {
    ...
    @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));
        }
    }
    
    static final class ObserveOnObserver<T> extends BasicIntQueueDisposable<T>
    implements Observer<T>, Runnable {
        
         @Override
        public void onNext(T t) {
            ...
            // 把结果放入队列中
            if (sourceMode != QueueDisposable.ASYNC) {
                queue.offer(t);
            }
            schedule();
        }
        
        void schedule() {
            if (getAndIncrement() == 0) {
                // worker执行
                worker.schedule(this);
            }
        }
    }

上游的结果存放到队列中,接下来执行线程切换。

HandlerScheduler创建的Worker是HandlerWorker,具体执行如下:

private static final class HandlerWorker extends Worker {
    private final Handler handler;
    
    @Override
    public Disposable schedule(Runnable run, long delay, TimeUnit unit) {
        ...
			
        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, Math.max(0L, unit.toMillis(delay)));
        ...
    }
    
    private static final class ScheduledRunnable implements Runnable, Disposable {
        private final Handler handler;
        private final Runnable delegate;

        private volatile boolean disposed;

        ScheduledRunnable(Handler handler, Runnable delegate) {
            this.handler = handler;
            this.delegate = delegate;
        }

        @Override
        public void run() {
            ...
            delegate.run();
        }
    
}

可以看到是用Handler发了个Message,ScheduledRunnable只是用来处理异常,最终执行的是ObserveOnObserver的run()方法,这时已经切换到了主线程

static final class ObserveOnObserver<T> extends BasicIntQueueDisposable<T>
    implements Observer<T>, Runnable {
    ...
    @Override
    public void run() {
        if (outputFused) {
            drainFused();
        } else {
            drainNormal();
        }
    }
    
    void drainNormal() {
            int missed = 1;

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

            for (;;) {
                ...
                for (;;) {
                    boolean d = done;
                    T v;
                    v = q.poll();
                    boolean empty = v == null;
                    ...
                    if (empty) {
                        break;
                    }
					// 通知下游
                    a.onNext(v);
                }
                ...
            }
        }
}

然后主线程里做的就是循环从队列中读取并不断调用onNext()向下游发送结果。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值