RxJava2实例源码浅析(3)-线程调度

从最简单的例子着手,一步步看RxJava内部是如何封装调用的

Flowable.just("hello")
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new FlowableSubscriber<String>() {
                    @Override
                    public void onSubscribe(@NonNull Subscription subscription) {
                        subscription.request(Long.MAX_VALUE);
                    }

                    @Override
                    public void onNext(String s) {
                        textView.append(s+"\n");
                    }

                    @Override
                    public void onError(Throwable throwable) {
                    }

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

这个例子用到了RxJava2的线程切换,最终输出"hello"


1.线程调度器Scheduler


一.先来分析Schedulers.io()


Schedulers可以理解是Scheduler的集合,内部保存了各种类型的Scheduler,方便直接获取。看下io()返回的是什么Scheduler

@NonNull
    public static Scheduler io() {
        return RxJavaPlugins.onIoScheduler(IO);
    }
@NonNull
    public static Scheduler onIoScheduler(@NonNull Scheduler defaultScheduler) {
        Function f = onIoHandler; //onIoHandler默认是null
        return f == null?defaultScheduler:(Scheduler)apply(f, defaultScheduler);
    }
看出io()直接返回IO这个Scheduler

@NonNull
    static final Scheduler IO = RxJavaPlugins.initIoScheduler(new Schedulers.IOTask());
 ##这里先看下传入的参数IOTask是什么

static final class IOTask implements Callable<Scheduler> {
        IOTask() {
        }

        public Scheduler call() throws Exception {
            return Schedulers.IoHolder.DEFAULT;
        }
    }

 ##它继承并实现了Callable接口(Callable和Runnable都是用于多线程的接口,区别是一个有返回值,一个没有)


回头看initIoScheduler方法

@NonNull
    public static Scheduler initIoScheduler(@NonNull Callable<Scheduler> defaultScheduler) {
        ObjectHelper.requireNonNull(defaultScheduler, "Scheduler Callable can\'t be null");
        Function f = onInitIoHandler; //默认是null
        return f == null?callRequireNonNull(defaultScheduler):applyRequireNonNull(f, defaultScheduler);
    }
@NonNull
    static Scheduler callRequireNonNull(@NonNull Callable<Scheduler> s) {
        try {
            return (Scheduler)ObjectHelper.requireNonNull(s.call(), "Scheduler Callable result can\'t be null"); //关键s.call()
        } catch (Throwable var2) {
            throw ExceptionHelper.wrapOrThrow(var2);
        }
    }
最终返回的是s.call()方法的返回值即Schedulers.IoHolder.DEFAULT,所以Schedulers.io()其实获取的就是Schedulers.IoHolder.DEFAULT,下面看看这个DEFAULT是什么调度器

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

        IoHolder() {
        }
    }
public final class IoScheduler extends Scheduler {
    ...
    public IoScheduler() {
        this(WORKER_THREAD_FACTORY);
    }

    public IoScheduler(ThreadFactory threadFactory) {
        this.threadFactory = threadFactory;
        this.pool = new AtomicReference(NONE);
        this.start();
    }

    static {
        KEEP_ALIVE_UNIT = TimeUnit.SECONDS;
        SHUTDOWN_THREAD_WORKER = new IoScheduler.ThreadWorker(new RxThreadFactory("RxCachedThreadSchedulerShutdown")); //RxThreadFactory是自定义线程工厂,主要作了设置线程名称、优先级、将线程设为守护线程等辅助行为
        SHUTDOWN_THREAD_WORKER.dispose(); //调用ScheduledThreadPoolExctuor.shutdownNow(),作用是立即关闭线程池
        int priority = Math.max(1, Math.min(10, Integer.getInteger("rx2.io-priority", 5).intValue())); //这里计算出来的优先级是5
        WORKER_THREAD_FACTORY = new RxThreadFactory("RxCachedThreadScheduler", priority);
        EVICTOR_THREAD_FACTORY = new RxThreadFactory("RxCachedWorkerPoolEvictor", priority);
        NONE = new IoScheduler.CachedWorkerPool(0L, (TimeUnit)null, WORKER_THREAD_FACTORY);
        NONE.shutdown(); //关闭线程池
    }
    ...
}

##详细分析初始化做了哪些操作

  1)静态代码块

  • SHUTDOWN_THREAD_WORKER:实例化一个ThreadWorker,继承NewThreadWorker,又继承Worker(Worker是RxJava定义的类,通过它调用Runnable)。在NewThreadWorker的构造方法中实例化了一个ScheduledThreadPoolExecutor(用于多线程下定时/延迟任务的执行),并缓存进SchedulerPoolFactory.POOLS中
  • NONE:实例化CacheWorkerPool,该类继承并实现Runnable接口。构造方法中也创建并保存了一个ScheduledThreadPoolExecutor

2)构造方法

  • pool:创建AtomicReference对象,初始化它的值为NONE
  • start():该方法就是重新new了一个CacheWorkerPool,keepAliveTime为60,替换pool中的值为它

看到这里我们知道Schedulers.io()创建返回的是IoScheduler对象,后面可以直接到这个类中查看方法。

二.AndroidSchedulers.mainThread()

这个线程调度器是专门为Android定制的,可以指定后面的代码运行在UI线程,看看代码实现
private static final Scheduler MAIN_THREAD = RxAndroidPlugins.initMainThreadScheduler(
            new Callable<Scheduler>() {
                @Override public Scheduler call() throws Exception {
                    return MainHolder.DEFAULT;
                }
            });

    /** A {@link Scheduler} which executes actions on the Android main thread. */
    public static Scheduler mainThread() {
        return RxAndroidPlugins.onMainThreadScheduler(MAIN_THREAD); //这里直接返回MAIN_THREAD
    }
内部经过各种转换比较最终会返回MainHolder.DEFAULT对象
private static final class MainHolder {
        static final Scheduler DEFAULT = new HandlerScheduler(new Handler(Looper.getMainLooper()));
    }
AndroidSchedulers.mainThread()创建返回的是HandlerScheduler对象,其继承Scheduler,内部保存了Android主线程的Handler。

2.subscribeOn指定订阅时所在的线程


进入subcribeOn查看源码

@CheckReturnValue
    @BackpressureSupport(BackpressureKind.PASS_THROUGH)
    @SchedulerSupport("custom")
    public final Flowable<T> subscribeOn(@NonNull Scheduler scheduler) {
        ObjectHelper.requireNonNull(scheduler, "scheduler is null");
        return this.subscribeOn(scheduler, !(this instanceof FlowableCreate)); //传入IoScheduler和true
    }
@CheckReturnValue
    @BackpressureSupport(BackpressureKind.PASS_THROUGH)
    @SchedulerSupport("custom")
    @Experimental
    public final Flowable<T> subscribeOn(@NonNull Scheduler scheduler, boolean requestOn) {
        ObjectHelper.requireNonNull(scheduler, "scheduler is null");
        return RxJavaPlugins.onAssembly(new FlowableSubscribeOn(this, scheduler, requestOn)); //这里原样返回FlowableSubscribeOn对象
    }
看出该方法创建了FlowableSubscribeOn,传入FlowableJust自身、IoScheduler、true包装保存,该对象也继承自Flowable。

public FlowableSubscribeOn(Flowable<T> source, Scheduler scheduler, boolean nonScheduledRequests) {
        super(source);
        this.scheduler = scheduler;
        this.nonScheduledRequests = nonScheduledRequests;
    }

执行完subscribeOn方法这里返回的是一个FlowableSubscribeOn对象,这个对象保存了上游传下来的FlowableJust和IoScheduler。


3.observeOn切换线程


进入方法内部

@CheckReturnValue
    @BackpressureSupport(BackpressureKind.FULL)
    @SchedulerSupport("custom")
    public final Flowable<T> observeOn(Scheduler scheduler, boolean delayError, int bufferSize) { //传入的delayError为false,bufferSize为128
        ObjectHelper.requireNonNull(scheduler, "scheduler is null"); 
        ObjectHelper.verifyPositive(bufferSize, "bufferSize");
        return RxJavaPlugins.onAssembly(new FlowableObserveOn(this, scheduler, delayError, bufferSize));
    }
创建并 返回 FlowableObserveOn对象,该对象保存了上游传下来的FlowableSubscribeOn和HandlerScheduler。

public FlowableObserveOn(Flowable<T> source, Scheduler scheduler, boolean delayError, int prefetch) {
        super(source);  //FlowableSubscribeOn
        this.scheduler = scheduler;   //HandlerScheduler
        this.delayError = delayError; //false
        this.prefetch = prefetch;     //128
    }

4.subscribe订阅


接下来就是执行订阅的方法了,真正执行订阅的地方在FlowableObserveOn.subscribeActual方法中

public void subscribeActual(Subscriber<? super T> s) {
        Worker worker = this.scheduler.createWorker(); //调用HandlerScheduler,返回HandlerWorker
        if(s instanceof ConditionalSubscriber) { //s是FlowableSubscriber,比较结果是false
            this.source.subscribe(new FlowableObserveOn.ObserveOnConditionalSubscriber((ConditionalSubscriber)s, worker, this.delayError, this.prefetch));
        } else {
            this.source.subscribe(new FlowableObserveOn.ObserveOnSubscriber(s, worker, this.delayError, this.prefetch)); //调用FlowableSubscribeOn的subscribe方法;ObserveOnSubscriber对象将我们实现的FlowableSubscriber、HandlerWorker、FlowableObserveOn、false、128等参数包装进去后面用到
        }
    }

现在执行到了FlowableSubscribeOn的subscribe方法,这个方法实际执行subscribeActual方法,

分析里面做了哪些操作:

public void subscribeActual(Subscriber<? super T> s) {
        Worker w = this.scheduler.createWorker(); //调用IoScheduler的createWorker方法,返回EventLoopWorker对象
        FlowableSubscribeOn.SubscribeOnSubscriber sos = new FlowableSubscribeOn.SubscribeOnSubscriber(s, w, this.source, this.nonScheduledRequests); //创建SubscribeOnSubscriber对象,将ObserveOnSubscriber、EventLoopWorker、FlowableJust、true传入
        s.onSubscribe(sos);
        w.schedule(sos);
    }

1)s.onSubscribe(sos); 即ObserveOnSubscriber.onSubscribe(SubscribeOnSubscriber)

public void onSubscribe(Subscription s) {
            if(SubscriptionHelper.validate(this.s, s)) {
                this.s = s;
                if(s instanceof QueueSubscription) { //比较结果为false
                    QueueSubscription f = (QueueSubscription)s;
                    int m = f.requestFusion(7);
                    if(m == 1) {
                        this.sourceMode = 1;
                        this.queue = f;
                        this.done = true;
                        this.actual.onSubscribe(this);
                        return;
                    }

                    if(m == 2) {
                        this.sourceMode = 2;
                        this.queue = f;
                        this.actual.onSubscribe(this);
                        s.request((long)this.prefetch);
                        return;
                    }
                }

                this.queue = new SpscArrayQueue(this.prefetch);
                this.actual.onSubscribe(this);
                s.request((long)this.prefetch);
            }
        }
看倒数第二句,this.actual就是我们创建的FlowableSubscriber,在onSubscribe方法中执行subscription.request(Long.MAX_VALUE)。查看ObserveOnSubscriber的request代码:

public final void request(long n) {
            if(SubscriptionHelper.validate(n)) {
                BackpressureHelper.add(this.requested, n); //RxJava的一种背压策略
                this.trySchedule(); //关键看这句,调用了实例化时保存的HandlerWorker的schedule方法
            }
        }

final void trySchedule() { 
            if(this.getAndIncrement() == 0) { //原子操作,这里相当于i++
                this.worker.schedule(this); //worker是HandlerWorker
            }
        }


schedule方法先调用的父类Worker的schedule,然后再调用HandlerWorker的schedule

@Override
        public Disposable schedule(Runnable run, long delay, TimeUnit unit) {
            if (run == null) throw new NullPointerException("run == null"); //这里的run即ObserveOnSubscriber
            if (unit == null) throw new NullPointerException("unit == null");

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

            run = RxJavaPlugins.onSchedule(run); //这里原样返回

            ScheduledRunnable scheduled = new ScheduledRunnable(handler, run); //把主线程Handler和ObserveOnSubscriber包装进去

            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))); //这里延迟0,立即发送,在主线程响应

            // 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;
        }


2)w.schedule(sos); 即EventLoopWorker.schedule(SubscribeOnSubscriber),最终会调用

@NonNull
        public Disposable schedule(@NonNull Runnable action, long delayTime, @NonNull TimeUnit unit) { //isDisposed默认false
            return (Disposable)(this.tasks.isDisposed()?EmptyDisposable.INSTANCE:this.threadWorker.scheduleActual(action, delayTime, unit, this.tasks));
        }
又调用threadWorker的父类中的scheduleActual方法

@NonNull
    public ScheduledRunnable scheduleActual(Runnable run, long delayTime, @NonNull TimeUnit unit, @Nullable DisposableContainer parent) {
        Runnable decoratedRun = RxJavaPlugins.onSchedule(run); //这里原样返回
        ScheduledRunnable sr = new ScheduledRunnable(decoratedRun, parent); //将SubscribeOnSubscriber包装进去
        if(parent != null && !parent.add(sr)) { //parent非空、add返回true
            return sr;
        } else {
            try {
                Object f;
                if(delayTime <= 0L) { //delayTime=0
                    f = this.executor.submit(sr); //交由ScheduledThreadPoolExecutor线程池运行
                } 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在线程池的线程中运行,它的run方法中又调用了 SubscribeOnSubscriber的run方法

public void run() {
            this.lazySet(Thread.currentThread());
            Publisher src = this.source;
            this.source = null;
            src.subscribe(this); //src即最开始just方法创建返回的FlowableJust对象
        }
此时已经是在另一个线程中执行了,即真正开始订阅的时候是在Schedulers.io()指定的线程中了


继续往下执行,会调用FlowableJust.subscribeActual->SubscribeOnSubscriber.onSubscribe方法->SubscribeOnSubscriber.requestUpStream方法->ScalarSubscription.request方法:

public void request(long n) { //n=128
        if(SubscriptionHelper.validate(n)) {
            if(this.compareAndSet(0, 1)) { //经过CAS值为1
                Subscriber s = this.subscriber; //s即SubscribeOnSubscriber
                s.onNext(this.value); //value="hello"
                if(this.get() != 2) {
                    s.onComplete();
                }
            }
        }
    }
s.onNext->SubscribeOnSubscriber.onNext->ObserveOnSubscriber的父类的onNext:

public final void onNext(T t) {
            if(!this.done) {
                if(this.sourceMode == 2) { //这里sourceMode=0
                    this.trySchedule();
                } else {
                    if(!this.queue.offer(t)) { //关键,这里将"hello"加入q队列,返回true
                        this.s.cancel();
                        this.error = new MissingBackpressureException("Queue is full?!");
                        this.done = true;
                    }

                    this.trySchedule(); //该方法上面分析过
                }
            }
        }
s.onComplete-> SubscribeOnSubscriber.onComplete->FlowableOnSubscriber.onComplete

public void onComplete() {
            this.actual.onComplete();
            this.worker.dispose(); //处理释放EventLoopWorker
        }
public final void onComplete() {
            if(!this.done) {
                this.done = true;
                this.trySchedule(); //该方法上面分析过
            }
        }
trySchedule方法会调用实例化时保存的XXWorker对象(这个例子中是HandlerWorker)的schedule方法,该方法会将包装过的Runnable通过Handler消息机制发送到Looper的线程执行。


在这个例子中

ScheduledRunnable scheduled = new ScheduledRunnable(handler, run); //把主线程Handler和ObserveOnSubscriber包装进去
Message message = Message.obtain(handler, scheduled);

handler发送消息后,等待MainLooper取出队列中的消息处理,通过Handler机制实现切换到主线程运行。因为message的callback为ScheduledRunnable,所以调用了ScheduledRunnable的run方法,它的run方法又调用了传入的ObserveOnSubscriber的run方法(该run方法在父类中):

public final void run() {
            if(this.outputFused) { //默认false
                this.runBackfused();
            } else if(this.sourceMode == 1) { //默认0
                this.runSync();
            } else {
                this.runAsync(); //该方法在子类实现
            }
        }
最终执行
void runAsync() {
            int missed = 1;
            Subscriber a = this.actual;
            SimpleQueue q = this.queue; //该队列会存放上游传进来的数据
            long e = this.produced;

            while(true) { 
                long r = this.requested.get();

                while(e != r) {
                    boolean w = this.done;

                    Object v;
                    try {
                        v = q.poll(); //从队列中取出数据
                    } catch (Throwable var11) {
                        Exceptions.throwIfFatal(var11);
                        this.s.cancel();
                        q.clear();
                        a.onError(var11);
                        this.worker.dispose();
                        return;
                    }

                    boolean empty = v == null;
                    if(this.checkTerminated(w, empty, a)) { //关键,该方法根据done和数据是否空判断是否退出循环
                        return;
                    }

                    if(empty) {
                        break;
                    }

                    a.onNext(v); //关键,调用了我们创建的FlowableSubscriber的onNext,并传入"hello"
                    ++e;
                    if(e == (long)this.limit) {
                        if(r != 9223372036854775807L) {
                            r = this.requested.addAndGet(-e);
                        }

                        this.s.request(e);
                        e = 0L;
                    }
                }

                if(e == r && this.checkTerminated(this.done, q.isEmpty(), a)) {
                    return;
                }

                int var12 = this.get();
                if(missed == var12) {
                    this.produced = e;
                    missed = this.addAndGet(-missed);
                    if(missed == 0) {
                        return;
                    }
                } else {
                    missed = var12;
                }
            }
        }

checkTerminated方法根据done标识和队列有无数据判断是否完成,在该方法内部最终调用我们创建的FlowableSubscriber的onComplete方法。


RxJava2通过层层包装和回调,实现了强大的功能。以上就是这个例子中,代码内部的大致调用流程。如有错误,请指正。







猜你喜欢

转载自blog.csdn.net/dehang0/article/details/79135015