RxJava线程切换原理

这篇文章跟上一篇的RxJava执行流程有关联性,没阅读上一篇的先瞅一下。

怎么进行线程切换的

subscribeOn(Schedulers.io())

首先了解下Scheduler.io()方法,它返回的是一个Scheduler,Scheduler是一个抽象方法,我们知道抽象方法是不能被实例化的,那么返回的肯定是它的实现类:

   public static Scheduler io() {
        return RxJavaPlugins.onIoScheduler(IO);
    }

上面代码里的IO对象是什么呢?

  IO = RxJavaPlugins.initIoScheduler(new Callable<Scheduler>() {
        @Override
        public Scheduler call() throws Exception {
            return IoHolder.DEFAULT;
        }
    });

    static final class IoHolder {
        static final Scheduler DEFAULT = new IoScheduler();
    }

答案是IoScheduler对象。

在前面的学习中,我们知道了subscribeOn(Schedulers.io())返回的对象是ObservableSubscribeOb对象


    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 Runnable() {
            @Override
            public void run() {
                source.subscribe(parent);
            }
        }));
    }

source.subscribe(parent) 被放在一个Runnable中执行,那么他是否已经就在子线程执行了呢?

NO,NO,NO,这还得看Runnable是被放在哪个线程上的,说不定是mainThread呢。

先看看scheduleDirect方法

  //无延迟执行
  public Disposable scheduleDirect(Runnable run) {
        return scheduleDirect(run, 0L, TimeUnit.NANOSECONDS);
    }

scheduleDirect.java

 public Disposable scheduleDirect(Runnable run, long delay, TimeUnit unit) {
        //createWorker是一个抽象方法,创建一个可以可以执行 run 的 worker 
        final Worker w = createWorker();
        //对 run 进行了包装,实际上还是 run 这个对象
        final Runnable decoratedRun = RxJavaPlugins.onSchedule(run);
        //decoratedRun 交给了 worker 去执行
        w.schedule(new Runnable() {
            @Override
            public void run() {
                try {
                    decoratedRun.run();
                } finally {
                    w.dispose();
                }
            }
        }, delay, unit);

        return w;
    }

直指IoScheduler#createWorker()

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

EventLoopWorker.java

 static final class EventLoopWorker extends Scheduler.Worker {
        //省略部分code

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

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

EventLoopWorker extends Scheduler.Worker ,Worker这个抽象类有个schedule()抽象方法需要重写,所以这个类的核心逻辑就在schedule()方法里:==threadWorker.scheduleActual(action, delayTime, unit, tasks);== ,点击进去看看:

public class NewThreadWorker extends Scheduler.Worker implements Disposable {
    //executor  是一个线程池
    private final ScheduledExecutorService executor;

    volatile boolean disposed;

    public NewThreadWorker(ThreadFactory threadFactory) {
        executor = SchedulerPoolFactory.create(threadFactory);
    }

    //省略部分代码

    public ScheduledRunnable scheduleActual(final Runnable run, long delayTime, TimeUnit unit, DisposableContainer parent) {
            //对传进来的run进行包装
            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);
                }

                //拿到f,传给ScheduledRunnable
                sr.setFuture(f);
            } catch (RejectedExecutionException ex) {
                parent.remove(sr);
                RxJavaPlugins.onError(ex);
            }

            return sr;
        }

ScheduledRunnable里面又做了什么?

  @Override
    public void run() {
        try {
            try {
                //actual就是通过构造函数传递进来的Runnable
                actual.run();
            } catch (Throwable e) {
                // Exceptions.throwIfFatal(e); nowhere to go
                RxJavaPlugins.onError(e);
            }
        } finally {
            Object o = get(PARENT_INDEX);
            if (o != DISPOSED && o != null && compareAndSet(PARENT_INDEX, o, DONE)) {
                ((DisposableContainer)o).delete(this);
            }

            for (;;) {
                o = get(FUTURE_INDEX);
                if (o == DISPOSED || compareAndSet(FUTURE_INDEX, o, DONE)) {
                    break;
                }
            }
        }
    }

“故事”的最终还是交给actual.run()去执行,也就是执行==source.subscribe(parent);== 几经“旋转跳跃”,它投入了子线程的怀抱。

小结

切换到子线程的逻辑还是比较容易的,利用线程池而已….

observeOn(AndroidSchedulers.mainThread())

首先了解下AndroidSchedulers.mainThread()

    /** A {@link Scheduler} which executes actions on the Android main thread. */
    public static Scheduler mainThread() {
        return RxAndroidPlugins.onMainThreadScheduler(MAIN_THREAD);
    }


    private static final Scheduler MAIN_THREAD = RxAndroidPlugins.initMainThreadScheduler(
            new Callable<Scheduler>() {
                @Override public Scheduler call() throws Exception {
                    return MainHolder.DEFAULT;
                }
            });

    private static final class MainHolder {

        static final Scheduler DEFAULT = new HandlerScheduler(new Handler(Looper.getMainLooper()));
    }

可以清楚的知道AndroidSchedulers.mainThread()返回的Schedule类是HandlerScheduler,内持有一个可以在主线程发送消息的handler对象。

接下来将代码定位到ObservableObserveOn#subscribeActual()方法

 protected void subscribeActual(Observer<? super T> observer) {
        //TrampolineScheduler是在当前线程执行的,但不是立即执行,需要等当前的工作单元都执行结束后。
        if (scheduler instanceof TrampolineScheduler) {
            source.subscribe(observer);
        } else {
            //这个schedule是HandlerScheduler,创建了一个 Scheduler.Worker
            Scheduler.Worker w = scheduler.createWorker();

            source.subscribe(new ObserveOnObserver<T>(observer, w, delayError, bufferSize));
        }
    }
ObserveOnObserver
@Override
public void onNext(T t) {
    if (done) {
        return;
    }

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

    //划重点!
    schedule();
}
void schedule() {
    if (getAndIncrement() == 0) {
        worker.schedule(this);
    }
}

==getAndIncrement() == 0== 是校验没有原子性,没有多个任务在同时执行

scheduler.createWorker()做了什么?

HandlerScheduler
 @Override
    public Worker createWorker() {
        return new HandlerWorker(handler);
    }

    private static final class HandlerWorker extends Worker {
        private final Handler handler;

        private volatile boolean disposed;

        HandlerWorker(Handler handler) {
            this.handler = handler;
        }

        @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, Math.max(0L, 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;
        }

        //省略部分代码

    }

在HandlerWorker#schedule()方法里通过Handler发送Message,Message中的callback对应run对象。

我们都知道Handler发送消息后会在dispatchMessage()方法处理

public void dispatchMessage(Message msg) {
    if (msg.callback != null) {
        handleCallback(msg);
    } else {
        if (mCallback != null) {
            if (mCallback.handleMessage(msg)) {
                return;
            }
        }
        handleMessage(msg);
    }
}



private static void handleCallback(Message message) {
    message.callback.run();
}

清楚的看到了业务逻辑执行==message.callback.run();== 也就是说ScheduledRunnable会被执行,ScheduledRunnable是ObserveOnObserver#schedule()方法里被传入的。

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

它传入的是this,那么最终执行的是ObserveOnObserver#run()方法了。

   @Override
    public void run() {
        //outputFused默认值为false
        if (outputFused) {
            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);
                        return;
                    }
                    boolean empty = v == null;

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

                    if (empty) {
                        break;
                    }

                    a.onNext(v);
                }

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

自上而下看了过来,找到了 ==a.onNext(v);== ,记住它现在所在的是主线程。

小结
  • 1、==AndroidSchedulers.MainThread()==,这个Scheduler(HandlerScheduler)它持有在主线程执行的Handle。
  • 2、ObserveOn返回的对象是==ObservableObserveOn==,封装了一个持有原观察者的Observer(ObserveOnObserver),它实现了Runnable接口,当执行到onNext()时,执行了Scheduler.Worker#schedule(Runnable)方法,并把this传递进去了。
  • HandlerScheduler.HandlerWorker#schedule()方法里用handle发送Message,而这个Message的callback就是之前传递进来的this(Runnable),最终在dispathMessage()方法里得到了执行,也就是执行run方法。回调到ObservableObserveOn.Observer#run()方法执行actual.onNext(),因为handle所在的线程是主线程,所以onNext(T t)所在的线程也是主线程。

一句话总结RxJava子线程和主线程的原理

切换到子线程的关键是将Runnable放到线程池去执行,切换到主线程是利用在主线程实例化的Handle发送Message,让runnable回调到主线程去。

猜你喜欢

转载自blog.csdn.net/dawN4get/article/details/80102677