Rxjava2 线程切换调度源码分析(二)

先上代码

Observable.create(

            // 自定义source
            new ObservableOnSubscribe<String>() {
                @Override
                public void subscribe(ObservableEmitter<String> e) throws Exception {
                    e.onNext("A");

                    Log.d(L.TAG, "自定义source: " + Thread.currentThread().getName());
                }
    })

    // ObservbaleCreate.subscribeOn
    // TODO 第二步     new IOScheduler ---> 线程池 传递进去
    .subscribeOn(

            // TODO 第一步  到底干了什么 ( new IOScheduler ---> 线程池)
            Schedulers.io() // 耗时读取的异步

            // Schedulers.newThread() // 开启新线程

    )

     // A线程. subscribe
     //  ObservableSubscribeOn.subscribe
    .subscribe(

            // 终点
            new Observer<String>() {
                @Override
                public void onSubscribe(Disposable d) {

                    Disposable disposable = d;
                    Log.d(L.TAG, "onSubscribe: " +  Thread.currentThread().getName());
                }

                @Override
                public void onNext(String s) {
                    Log.d(L.TAG, "onNext: " + Thread.currentThread().getName());
                }

                @Override
                public void onError(Throwable e) {

                }

                @Override
                public void onComplete() {

                }
    });
}

 

只要先分析

.subscribeOn(

        // TODO 第一步  到底干了什么 ( new IOScheduler ---> 线程池)
        Schedulers.io() // 耗时读取的异步

        // Schedulers.newThread() // 开启新线程

)

 

第一部看看Schedulers.io()

看一下这个io()是什么

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

 

public static Scheduler onIoScheduler(@NonNull Scheduler defaultScheduler) {
    Function<? super Scheduler, ? extends Scheduler> f = onIoHandler;
    if (f == null) {
        return defaultScheduler;
    }
    return apply(f, defaultScheduler);
}

又是一个hook方法

// TODO Hook  IO 传递进去的Hook
RxJavaPlugins.setIoSchedulerHandler(new Function<Scheduler, Scheduler>() {
    @Override
    public Scheduler apply(Scheduler scheduler) throws Exception {
        Log.d(L.TAG, "apply: 全局 监听 scheduler:" +scheduler);
        return scheduler;
    }
});

这里要使用的话可以这么使用不作多分析,主要看下IO是什么

Schedulers.java中
@NonNull
static final Scheduler IO;
IO = RxJavaPlugins.initIoScheduler(new IOTask());

initIoScheduler又是一个全局hook不分析了看下 IOTask(),继续跟踪

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

看到这里就是一个任务,带返回值的任务

进去IoHolder

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

进去IoScheduler

public IoScheduler() {
    this(WORKER_THREAD_FACTORY);
}

进去this

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

进去start

public void start() {
    CachedWorkerPool update = new CachedWorkerPool(KEEP_ALIVE_TIME, KEEP_ALIVE_UNIT, threadFactory);
    if (!pool.compareAndSet(NONE, update)) {
        update.shutdown();
    }
}

进去shutdown

  void shutdown() {
        allWorkers.dispose();
        if (evictorTask != null) {
            evictorTask.cancel(true);
        }
        if (evictorService != null) {
            evictorService.shutdownNow();
        }
    }
}

进入evictorService 在

private final ScheduledExecutorService evictorService;

很明显这是一个线程池

所以这一步可以实际上是做了new了一个IoScheduler到线程池

接下来再看

.subscribeOn(

        // TODO 第一步  到底干了什么 ( new IOScheduler ---> 线程池)
        Schedulers.io() // 耗时读取的异步

        // Schedulers.newThread() // 开启新线程

)

这个subscribeOn方法做了什么

进入subscribeOn

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

 

public final class ObservableSubscribeOn<T> extends AbstractObservableWithUpstream<T, T> {
    final Scheduler scheduler;

    public ObservableSubscribeOn(ObservableSource<T> source, Scheduler scheduler) {
        super(source);
        this.scheduler = scheduler;
    }

 

所以这里的把第一步new出来的IOScheduler给到scheduler

ObservableSubscribeOn final Scheduler scheduler; = ioScheduler(线程池的)

 

第三步

 

Observable.create(

        // 自定义source
        new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> e) throws Exception {
                e.onNext("A");

                Log.d(L.TAG, "自定义source: " + Thread.currentThread().getName());
            }
})

// ObservbaleCreate.subscribeOn
// TODO 第二步     new IOScheduler ---> 线程池 传递进去
.subscribeOn(

        // TODO 第一步  到底干了什么 ( new IOScheduler ---> 线程池)
        Schedulers.io() // 耗时读取的异步

        // Schedulers.newThread() // 开启新线程

)
// A线程. subscribe
//  ObservableSubscribeOn.subscribe
.subscribe(

        // 终点
        new Observer<String>() {
            @Override
            public void onSubscribe(Disposable d) {

                Disposable disposable = d;
                Log.d(L.TAG, "onSubscribe: " +  Thread.currentThread().getName());
            }

            @Override
            public void onNext(String s) {
                Log.d(L.TAG, "onNext: " + Thread.currentThread().getName());
            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onComplete() {

            }
});

通过上一篇分析知道Observable.create实际上是new一个ObservbaleCreate

所以这里是// ObservbaleCreate.subscribeOn

.subscribeOn实际上是new ObservableSubscribeOn

所以订阅是ObservableSubscribeOn.subscribe

进去订阅方法

@SchedulerSupport(SchedulerSupport.NONE)
@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;
    }
}

进入subscribeActual

protected abstract void subscribeActual(Observer<? super T> observer);
 抽象方法直接看实现ObservableSubscribeOn中
@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)));
}

 

这是的s就是我们的终点,自定义观察者,这里又进行了封装parent

先看new SubscribeTask(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);
    }
}

很明显这是一个任务,里面包含了终点的对象,是给线程池运行的

 

再看scheduler.scheduleDirect(new SubscribeTask(parent))

scheduler是之前说的ioScheduler线程池

scheduler.scheduleDirect(new SubscribeTask(parent))实际上

ioScheduler(线程池的).scheduleDirect(new SubscribeTask(parent)) 把我们的new SubscribeTask(parent)任务传进去

 

进去scheduleDirect  

Scheduler中
@NonNull
public Disposable scheduleDirect(@NonNull Runnable run) {
    return scheduleDirect(run, 0L, TimeUnit.NANOSECONDS);
}

进入scheduleDirect

public Disposable scheduleDirect(@NonNull Runnable run, long delay, @NonNull TimeUnit unit) {
    final Worker w = createWorker();

    final Runnable decoratedRun = RxJavaPlugins.onSchedule(run);

    DisposeTask task = new DisposeTask(decoratedRun, w);

    w.schedule(task, delay, unit);

    return task;
}

进去createWorker

@NonNull
public abstract Worker createWorker();

Scheduler是个父类,它有很多子类,在这里子类是

public final class IoScheduler extends Scheduler 

直接去这里看createWorker方法

IoScheduler 中

@Override
public Worker createWorker() {
    return new EventLoopWorker(pool.get());
}
static final class EventLoopWorker extends Scheduler.Worker {
    private final CompositeDisposable tasks;
    private final CachedWorkerPool pool;
    private final ThreadWorker threadWorker;

    final AtomicBoolean once = new AtomicBoolean();

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

    @Override
    public void dispose() {
        if (once.compareAndSet(false, true)) {
            tasks.dispose();

            // releasing the pool should be the last action
            pool.release(threadWorker);
        }
    }

    @Override
    public boolean isDisposed() {
        return once.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;
        }

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

这里是把这个EventLoopWorker类给创建了出来

 

回到前面这里

// 红色 Runnable
 @NonNull
  public Disposable scheduleDirect(@NonNull Runnable run, long delay, @NonNull TimeUnit unit) {
      final Worker w = createWorker();   == IoScheduler.createWorker(){new EventLoopWorker(pool.get());}

      // 自己包装 Runnable  ==  Runnable
      final Runnable decoratedRun = RxJavaPlugins.onSchedule(run);

      // 又包装一层 Runnable
      DisposeTask task = new DisposeTask(decoratedRun, w);

      w.schedule(task, delay, unit);

      return task;
  }

所以就有

final Worker w = createWorker();  == IoScheduler.createWorker(){new EventLoopWorker(pool.get());}

这里的run是我们前面的run任务,后面两个都是对这里run的再次封装

最主要是 w.schedule(task, delay, unit);,这里的w就是EventLoopWorker

去看EventLoopWorker中的schedule方法

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

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

 

进入scheduleActual

public ScheduledRunnable scheduleActual(final Runnable run, long delayTime, @NonNull TimeUnit unit, @Nullable DisposableContainer parent) {
    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);
        }
        sr.setFuture(f);
    } catch (RejectedExecutionException ex) {
        if (parent != null) {
            parent.remove(sr);
        }
        RxJavaPlugins.onError(ex);
    }

    return sr;
}
f = executor.submit((Callable<Object>)sr);这里就是我们的线程池

回到ObservableSubscribeOn中的

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

所以scheduleDirect的主要就是把任务丢给线程池

ioScheduler(线程池的).scheduleDirect(new SubscribeTask(parent)) 把我们的new SubscribeTask(parent)任务传进去

 

当线程池一执行,就会执行任务SubscribeTask的run方法,这时候就是切换在在异步线程

 

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就是我们的上一层,parent是终点传了进来,又去调到上一层是ObservableCreat的subscribeActual方法中,所以后面的流程都是在异步中执行,后面的分析就跟上一偏分析一样了,直接上图

 

注意这个方法不参与线程调度,因为

在subscribeActual方法是先执行 observer.onSubscribe(parent);再去 source.subscribe(parent);

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

到这里

.subscribeOn{
         Schedulers.io() 

}

给上面代码分配异步线程就分析完了,接下来分析给下面代码分配主线程.

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

上代码

Observable.create(

        // 自定义source
        new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> e) throws Exception {
                e.onNext("Derry");

                Log.d(L.TAG, "自定义source: " + Thread.currentThread().getName());
            }
        })

        // TODO 第二步骤
        .observeOn(

                // TODO 第一步   主线程的 Handlnr
                AndroidSchedulers.mainThread()

        )

        // subsceOn(1)  // 会显示是这个线程的原因,上一层卡片是被1线程执行
        // subsceOn(2)
        // subsceOn(3)

        // observeOn(A)
        // observeOn(B)
        // observeOn(C) // 终点是被C执行


        // ObservableObserveOn.subscribe
        .subscribe(

                // 终点
                new Observer<String>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.d(L.TAG, "onSubscribe: " +  Thread.currentThread().getName());
                    }

                    @Override
                    public void onNext(String s) {
                        Log.d(L.TAG, "onNext: " + Thread.currentThread().getName());
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {

                    }
                });

}

先看 AndroidSchedulers.mainThread()

进去mainThread

public static Scheduler mainThread() {
    return RxAndroidPlugins.onMainThreadScheduler(MAIN_THREAD);
}

进入MAIN_THREAD

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

进入DEFAULT

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

进入HandlerScheduler

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

把我们的主线程传了进来

// TODO 第一步   主线程的 Handlnr
AndroidSchedulers.mainThread() 所以这一步的作用就是获取到主线程的 Handlnr

 

再看.observeOn

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

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

这里new了一个ObservableObserveOn,并把我们的主线程handler传了进来

调用订阅会执行

ObservableObserveOn中的
 

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

//这里有个判断如果当前线程是主线程就不会切换去耗费资源

 

这个HandlerScheduler是Scheduler子类所以会去到HandlerScheduler的createWorker

 

final class HandlerScheduler extends Scheduler
public Worker createWorker() {
    return new HandlerWorker(handler);
}

这里new了一个HandlerWorker

source是上一层,上一层是ObservableCreate

通过上一篇分析知道会调用到ObservableCreate中的

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

通过发射器用户实现调用到onNext,再调用到ObservableObserveOn中的

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

内部类中的onnext方法

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

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

进入schedule

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

这里的worker是从ObservableObserveOn中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));
    }
}

就是我们的主线程的handler,也就是HandlerScheduler

进入schedule

@NonNull
public Disposable schedule(@NonNull Runnable run) {
    return schedule(run, 0L, TimeUnit.NANOSECONDS);
}
public abstract Disposable schedule(@NonNull Runnable run, long delay, @NonNull TimeUnit unit);

这个是在HandlerScheduler extends Scheduler 中实现的

再调用schedule

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

这里一执行就会到主线程

ScheduledRunnable scheduled = new ScheduledRunnable(handler, run);

handler.sendMessageDelayed(message, Math.max(0L, unit.toMillis(delay)));、

 

也就是ObserveOnObserver中的run方法一执行就会到主线程

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

再进去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);
                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;
        }
    }
}

a.onNext(v);

这里的a就是我们的终点,所以是在主线程中调用终点.onnext;

所以结论切换主线程是在ObservableObserveOn中的onNext方法中完成的

上图

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值