RxJava2 源码分析笔记(三) 线程切换

RxJava2 源码分析笔记(一)

RxJava2 源码分析笔记(二)

终于来到线程切换

先看一个如何切线程的简略流程图

注: 上面蓝色主流程中  subscribeOn(Schedulers.io()) ,observeOn(AndroidSchedulers.mainThread())

        但是subscribeOn,observeOn他们即可以传主线程也可以传子线程

        这是让RxJava的线程可以灵活的回切换的关键!

====================================================================

先来看看

subscribeOn(Schedulers.io())

这个分为两个部分

|------ subscribeOn() 创建了一个 Runnable{  run{ source.subscribe(parent);  },核心是source.subscribe(parent),并传递  到Schedulers.io()创建的Scheduler中调用。

|------ Schedulers.io()返回一个 Scheduler就是一个用来新建线程并调度使用;

 

接下来就先看subscribeOn()是如何实现的(和map等数据变换操作一样,结构都是类似的)

/**
 *    subscribeOn  核心是new ObservableSubscribeOn<T>(this, scheduler)
 */   
 @CheckReturnValue
    @SchedulerSupport(SchedulerSupport.CUSTOM)
    public final Observable<T> subscribeOn(Scheduler scheduler) {
        ObjectHelper.requireNonNull(scheduler, "scheduler is null");
        
        return RxJavaPlugins.onAssembly(new ObservableSubscribeOn<T>(this, scheduler));
    }

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

    static final class SubscribeOnObserver<T> extends AtomicReference<Disposable> implements Observer<T>, Disposable {
 
        //...省略其他代码...
        
        @Override
        public void onNext(T t) {
            actual.onNext(t);
        }

       
    }

    //核心代码
    final class SubscribeTask implements Runnable {
        private final SubscribeOnObserver<T> parent;

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

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

回到上面subscribeActual,代码如下

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 <T>  parent 并传递到new SubscribeTask中 ,

SubscribeTask实现了Runnable,在它的run方法里面执行了source.subscribe(parent); 

 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传到调度器中 scheduler.scheduleDirect(new SubscribeTask(parent))

调度器scheduler是哪来的的呢,还记得前面 subscribeOn(Scheduler scheduler)么,它就是我们传递过来的 Schedulers.io() 。

那就看一下 Schedulers.io() 是什么样的

    //源码点进去就是这个
  
    @NonNull
    public static Scheduler io() {
        return RxJavaPlugins.onIoScheduler(IO);
    }

 而 RxJavaPlugins.onIoScheduler(IO) 点进去源码看了以后发现返回的的就是 IO

@NonNull
    public static Scheduler onIoScheduler(@NonNull Scheduler defaultScheduler) {
        Function f = onIoHandler; //onIoHandler为null
        return f == null?defaultScheduler:(Scheduler)apply(f, defaultScheduler);
    }

我们去看IO是什么就可以了

public final class Schedulers {
    
    ......

    @NonNull
    static final Scheduler IO;


    static {
        SINGLE = RxJavaPlugins.initSingleScheduler(new SingleTask());

        COMPUTATION = RxJavaPlugins.initComputationScheduler(new ComputationTask());

        // IO 在这里初始化
        IO = RxJavaPlugins.initIoScheduler(new IOTask());

        TRAMPOLINE = TrampolineScheduler.instance();

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


    ......

}

而 RxJavaPlugins.initIoScheduler(new IOTask()); 最后返回的就是new IOTask()的返回值为啥这么说呢

 

@NonNull
    public static Scheduler initIoScheduler(@NonNull Callable<Scheduler> defaultScheduler) {
        ObjectHelper.requireNonNull(defaultScheduler, "Scheduler Callable can\'t be null");
        Function f = onInitIoHandler;  //注释:onInitIoHandler为null 
        return f == null?callRequireNonNull(defaultScheduler):applyRequireNonNull(f, defaultScheduler);
    }

所以 RxJavaPlugins.initIoSchedule →  callRequireNonNull(defaultScheduler)(代码如下) 

@NonNull
    static Scheduler callRequireNonNull(@NonNull Callable<Scheduler> s) {
        try {
                                                         //s 
            return (Scheduler)ObjectHelper.requireNonNull(s.call(), "Scheduler Callable result can\'t be null");
        } catch (Throwable var2) {
            throw ExceptionHelper.wrapOrThrow(var2);
        }
    }

所以 callRequireNonNull(defaultScheduler) → ObjectHelper.requireNonNull(代码如下)
 
public final class ObjectHelper {

     public static <T> T requireNonNull(T object, String message) {
        if (object == null) {
            throw new NullPointerException(message);
        }
        return object; //注释 这个object就是s.call()  
    }

}

  接下来就看 s.call 方法是怎么回事

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

而  IoHolder.DEFAULT = new IoScheduler();

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

也就是说最终为:
     Schedulers.io() =  new IoScheduler();

最终我们得到了一个继承自 Scheduler 的  IoScheduler

public final class IoScheduler extends Scheduler {

.........................省略代码.............................


}

 

 

这样两个部分我们都已经得到接下来就看他们之间是如何调用的

调用开始的地方是这行代码:subscribeActual中的scheduler.scheduleDirect(new SubscribeTask(parent))

首先发现 IoScheduler 中并没有 scheduleDirect 方法,是因为这个是在其父类Scheduler 实现的

public abstract class Scheduler {
    
    @NonNull
    public Disposable scheduleDirect(@NonNull Runnable run) {
     注释: scheduler.scheduleDirect(new SubscribeTask(parent))先到这里
        return scheduleDirect(run, 0L, TimeUnit.NANOSECONDS);
    }

    public abstract Worker createWorker();

    public Disposable scheduleDirect(@NonNull Runnable run, long delay, @NonNull TimeUnit 
       unit) {
        核心代码 ↓  createWorker在Scheduler中是抽象方法具体实现在子类IoScheduler中
        final Worker w = createWorker();

        final Runnable decoratedRun = RxJavaPlugins.onSchedule(run);

        DisposeTask task = new DisposeTask(decoratedRun, w);
        
        这里就是子类createWorker得到 Worker w 调用schedule
        task就是subscribeOn创建的Runnable
            ↓
        w.schedule(task, delay, unit);

        return task;
    }

}
public final class IoScheduler extends Scheduler {

    注释:createWorker创建并返回了一个EventLoopWorker对象
    public Worker createWorker() {
        return new EventLoopWorker(pool.get());
    }
                            ↓
    static final class EventLoopWorker extends Scheduler.Worker {
        
        private final ThreadWorker threadWorker;

        
        EventLoopWorker(CachedWorkerPool pool) {
            this.pool = pool;
            this.tasks = new CompositeDisposable();
            this.threadWorker = pool.get();
        }

        
        @NonNull
        @Override
        public Disposable schedule(@NonNull Runnable action, long delayTime, @NonNull 
            TimeUnit unit) {
            if (tasks.isDisposed()) {
                // don't schedule, we are unsubscribed
                return EmptyDisposable.INSTANCE;
            }
            
            注释: threadWorker = pool.get(),
                  而pool.get()点进看到返回的是一个ThreadWorker
                  最终执行的是ThreadWorker.scheduleActual(action, delayTime, unit, tasks)
            return threadWorker.scheduleActual(action, delayTime, unit, tasks);
        }
    }
                            ↓
    static final class ThreadWorker extends NewThreadWorker {
        private long expirationTime;
        
        注释:但是在ThreadWorker 中并没有scheduleActual
             这个方法是在其父类NewThreadWorker中
        ThreadWorker(ThreadFactory threadFactory) {
            super(threadFactory);
            this.expirationTime = 0L;
        }

        public long getExpirationTime() {
            return expirationTime;
        }

        public void setExpirationTime(long expirationTime) {
            this.expirationTime = expirationTime;
        }
    }
      
}

下面就看NewThreadWorker 源码

public class NewThreadWorker extends Scheduler.Worker implements Disposable {

    public ScheduledRunnable scheduleActual(final Runnable run, long delayTime, @NonNull         
              TimeUnit unit, @Nullable DisposableContainer parent) {
        注释:这里将run 进行装饰封装最终传递到ScheduledRunnable sr中
        Runnable decoratedRun = RxJavaPlugins.onSchedule(run);

        ScheduledRunnable sr = new ScheduledRunnable(decoratedRun, parent);

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

        Future<?> f;
        try {
            注释: sr在这里执行也,就是Runnable在这里执行
            还记得Runnable的run执行的是啥不: source.subscribe(parent);
             // @Override
             // public void run() {
             //    source.subscribe(parent);
             // }  
            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;
    }

}

到这里subscribeOn(Schedulers.io()),在一个新线程里面.subscribe回去的就实现了

其实和其他操作像flatMap,map差不多,只不过.subscribe是在一个新线程里面执行

注: subscribeOn只有第一个起作用?

上图可以看到: 第一个subscribeOn新建Thread1; 第二个subscribeOn新建Thread2;

在调用链中首先执行第二个subscribeOn切换到Thread2执行了 .subscribe 方法,然后就到了第一个subscribeOn,切换到Thread1,之后的.subscribe.onNext都是在第一个subscribeOn创建的Thread1线程中执行。所以说只有第一个subscribeOn起作用,之后的subscribeOn也不能说没起作用,执行了.subscribe方法。。。(好像也并没啥有用)。

================================================================

下面就看看

observeOn(AndroidSchedulers.mainThread())

同样也分为两个部分

|------ observeOn() 也是创建了一个 Runnable{  run{  .onNext()  } },并传递到

         AndroidSchedulers.mainThread()创建的线程中调用。

|------ AndroidSchedulers.mainThread()返回一个线程来执行observeOn创建的Runnable;

先看observeOn

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));
    }
        ↓
        ↓
        ↓ 接着看ObservableObserveOn
        ↓
        ↓
        ↓


public final class ObservableObserveOn<T> extends AbstractObservableWithUpstream<T, T> {
         
     注释:scheduler就是我们传进来的AndroidSchedulers.mainThread()
     final Scheduler scheduler;
     
     public ObservableObserveOn(ObservableSource<T> source, Scheduler scheduler, boolean 
     delayError, int bufferSize) {
        super(source);
        this.scheduler = scheduler;
        ...
    }
    @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));
        }
    }

}

 Scheduler.Worker w = scheduler.createWorker() 看着有没有很熟悉

source.subscribe(new ObserveOnObserver<T>(observer, w, delayError, bufferSize)); 这里直接.subscribe是因为observeOn切换的是.onNext 向下传递数据的线程,而向上的.subscribe向上回调的线程是由subscribeOn控制的。

接下来就看 ObserveOnObserver 里面的.onNext是如何切换线程传递数据的

注意:ObserveOnObserver实现的了Runnable,
static final class ObserveOnObserver<T> extends BasicIntQueueDisposable<T>
    implements Observer<T>, Runnable {

     final Scheduler.Worker worker;

     ObserveOnObserver(Observer<? super T> actual, Scheduler.Worker worker, boolean 
                 delayError, int bufferSize) {
            
            this.worker = worker;
             ...
        }

       @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);
            }
        }
    
     public void run() {
            if (outputFused) {
                drainFused();
            } else {
                drainNormal();
            }
        }
     
     void drainNormal() {
           
            ...
            final Observer<? super T> a = actual;

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

                for (;;) {
                    
                    ......

                    a.onNext(v);

                }

               ......
            }
        }

}

 onNext中执行的是worker.schedule(this);

|------ worker:  scheduler.createWorker()

|------ this: 就是实现了Runnable的ObserveOnObserver本身

到这里observeOn就结束了,现在需要找到worker是怎么createWorker出来的

那接下来就要看传进来的scheduler是啥(其实就是我们传入的AndroidSchedulers.mainThread)。

 

AndroidSchedulers.mainThread()

public final class AndroidSchedulers { 

    public static Scheduler mainThread() {
        return RxAndroidPlugins.onMainThreadScheduler(MAIN_THREAD);
    }
            ↓
            ↓ RxAndroidPlugins.onMainThreadScheduler(MAIN_THREAD)返回的就是MAIN_THREAD
            ↓
    
   private static final Scheduler MAIN_THREAD = RxAndroidPlugins.initMainThreadScheduler(
           注释:这里看着也很熟悉,好像和Schedulers.io()差不多
             new Callable<Scheduler>() {
                @Override public Scheduler call() throws Exception {
                    return MainHolder.DEFAULT;
                }
            });
              ↓
              ↓ 是的没错最后得到的就是MainHolder.DEFAULT
              ↓ 

    private static final class MainHolder {
       static final Scheduler DEFAULT =
                     new HandlerScheduler(new Handler(Looper.getMainLooper()));
    }  
}

这样 AndroidSchedulers.mainThread() 我们最后得到就是一个HandlerScheduler对象,new  Handler(Looper.getMainLooper())

 是作为HandlerScheduler的构造参数传入的。

这样我们就得到了scheduler。

那就看scheduler.createWorker() 是怎么实现的了

final class HandlerScheduler extends Scheduler {
     注释:这个handler就是new Handler(Looper.getMainLooper())
     private final Handler handler;

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

    @Override
    public Worker createWorker() {
        注释1 ↓
        return new HandlerWorker(handler);
    }

  private static final class HandlerWorker extends Worker {
       
        private final Handler handler;
        
        HandlerWorker(Handler handler) {
            this.handler = handler;
        }

        @Override
        public Disposable schedule(Runnable run, long delay, TimeUnit unit) {
            ...

            run = RxJavaPlugins.onSchedule(run);

            ScheduledRunnable scheduled = new ScheduledRunnable(handler, run);

            Message message = Message.obtain(handler, scheduled);
            message.obj = this; 

            handler.sendMessageDelayed(message, unit.toMillis(delay));

            ...

            return scheduled;
        }

}

在 createWorker里面返回了 一个HandlerWorker对象,这样worker我们就找到了。

 还记得 onNext → schedule()么,schedule中调用worker.schedule(Runnable)

然而HandlerWorker 并没有schedule(  Runnable run)方法,因为这个实现是在他的父类Scheduler.Worker中

public abstract class Scheduler {
  
  public abstract static class Worker implements Disposable {

        @NonNull
        public Disposable schedule(@NonNull Runnable run) {

            注释 schedule(run, 0L, TimeUnit.NANOSECONDS)是下面的抽象方法
                 具体实现在其子类中,所以又回到了原来的HandlerWorker
            return schedule(run, 0L, TimeUnit.NANOSECONDS);
        }
    
   
    @NonNull
    public abstract Disposable schedule(@NonNull Runnable run, long delay, TimeUnit unit);

 
  }
}

还记得上面HandlerWorker 的源码么

  private static final class HandlerWorker extends Worker {
       
        private final Handler handler;
        
        HandlerWorker(Handler handler) {
            this.handler = handler;
        }

        @Override
        public Disposable schedule(Runnable run, long delay, TimeUnit unit) {
            ...

            run = RxJavaPlugins.onSchedule(run);

            ScheduledRunnable scheduled = new ScheduledRunnable(handler, run);
            
            注释: 核心代码
            Message message = Message.obtain(handler, scheduled);
            
            message.obj = this; 

            handler.sendMessageDelayed(message, unit.toMillis(delay));

            ...

            return scheduled;
        }

利用handler将Runnable放在主线程中执行,这样就切换到主线程了(这里我们传的是AndroidSchedulers.mainThread())

这样我们Runnable里面的run方法已经在主线程执行了

这时候我们可以去看一下Runnable(即:ObserveOnObserver)里面的 run 方法是如何执行的

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

    ...省略其它代码...

     public void run() {
            if (outputFused) {
                不走这里 这里执行的是onNext(null)传一个null回去
                drainFused();
            } else {
                执行这里
                drainNormal();
            }
        }
     
     void drainNormal() {
           
            ...
            final Observer<? super T> a = actual;

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

                for (;;) {
                    
                    ......
                    终于,数据在我们observeOn的线程中传递了回去
                    a.onNext(v);

                }

               ......
            }
        }

}

这样observeOn(AndroidSchedulers.mainThread())就结束了。

注:Rxjvava之所以灵活是因为可以在子线程主线程之间来回切换

observeOn之所以可以灵活切换线程核心代码是下面这个

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

        }
    }

如果你在observeOn中传入 Schedulers.newThread() ,scheduler就是NewThreadScheduler,scheduler.createWorker()得到的就是 NewThreadWorker 然后在在其中 executor.submit(Runnable)。

如果你在observeOn中传入 Schedulers.io() ,scheduler就是IoScheduler,scheduler.createWorker()得到的就是 EventLoopWorker然后在在其中 executor.submit(Runnable)。

如果你在observeOn中传入 AndroidSchedulers.mainThread() ,scheduler就是HandlerScheduler(new Handler(Looper.getMainLooper())),scheduler.createWorker()得到的就是 HandlerWorker然后在在其中执行:

Message message = Message.obtain(handler, scheduled);
message.obj = this;  
handler.sendMessageDelayed(message, unit.toMillis(delay));

至此,如何切换线程的就结束了。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值