RxJava系列(三)--切换线程

1.主线程是怎么切换到子线程
2.为什么只有第一次切换有效
3.子线程是怎么切换到主线程
1>问题1,主线程是怎么切换到子线程,实际上先不看源码,换做我们自己写的话,最简单的用Thread和Runnable就可以实现
那么从这行代码分析:

.subscribeOn(Schedulers.io())
public final Observable subscribeOn(Scheduler scheduler) {
        ObjectHelper.requireNonNull(scheduler, "scheduler is null");
        return RxJavaPlugins.onAssembly(new ObservableSubscribeOn(this, scheduler));
    }
public final class ObservableSubscribeOn extends AbstractObservableWithUpstream {
    final Scheduler scheduler;

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

    @Override
    public void subscribeActual(final Observer observer) {
        final SubscribeOnObserver parent = new SubscribeOnObserver(observer);

        observer.onSubscribe(parent);

        parent.setDisposable(scheduler.scheduleDirect(new SubscribeTask(parent)));
    }...
 final class SubscribeTask implements Runnable {
        private final SubscribeOnObserver parent;

        SubscribeTask(SubscribeOnObserver parent) {
            this.parent = parent;
        }

        @Override
        public void run() {
            source.subscribe(parent);
        }
    }
public Disposable scheduleDirect(@NonNull Runnable run) {
        return scheduleDirect(run, 0L, TimeUnit.NANOSECONDS);
    }
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;
    }

so,接下来看Schedulers的具体实现了.

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

缕缕头绪,实际就是一段代码:

createWorker().schedule(new Runnable() {
            @Override
            public void run() {
                source.subscribe(parent);
            }
        },0,TimeUnit.NANOSECONDS)
createWorker()-->Schedulers.io()
source-->ObservableCreate

那么接下来看一下Schedulers.io()的实现吧.

 public static Scheduler io() {
        return RxJavaPlugins.onIoScheduler(IO);
    }
static final class IoHolder {
        static final Scheduler DEFAULT = new IoScheduler();
    }
 public Worker createWorker() {
        return new EventLoopWorker(pool.get());
    }
 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);
        }
    }
 public ScheduledRunnable scheduleActual(final Runnable run, long delayTime, @NonNull TimeUnit unit, @Nullable DisposableContainer parent) {
     ... ScheduledRunnable sr = new ScheduledRunnable(decoratedRun, parent);
        try {
            if (delayTime <= 0) {
                f = executor.submit((Callable)sr);
            } else {
                f = executor.schedule((Callable)sr, delayTime, unit);
            }
            sr.setFuture(f);
        } catch (RejectedExecutionException ex) {
            if (parent != null) {
                parent.remove(sr);
            }
            RxJavaPlugins.onError(ex);
        }
        return sr;
    }
executor--->ScheduledExecutorService

总结:

executor.submit(new Runnable() {
            @Override
            public void run() {
                source.subscribe(parent);
            }
        })

2>为什么只有第一次切换有效


未命名文件 (1).png

看了流程图是不是明白链式调用了
3>子线程是怎么切换到主线程
接着还是按咱们平时的想法,用handler就可以

  public final Observable observeOn(Scheduler scheduler) {
        return observeOn(scheduler, false, bufferSize());
    }
public final Observable observeOn(Scheduler scheduler, boolean delayError, int bufferSize) {
        ObjectHelper.requireNonNull(scheduler, "scheduler is null");
        ObjectHelper.verifyPositive(bufferSize, "bufferSize");
        return RxJavaPlugins.onAssembly(new ObservableObserveOn(this, scheduler, delayError, bufferSize));
    }
public final class ObservableObserveOn extends AbstractObservableWithUpstream {
...
 @Override
    protected void subscribeActual(Observer observer) {
        if (scheduler instanceof TrampolineScheduler) {
            source.subscribe(observer);
        } else {
            Scheduler.Worker w = scheduler.createWorker();
            source.subscribe(new ObserveOnObserver(observer, w, delayError, bufferSize));
        }
    }

  static final class ObserveOnObserver extends BasicIntQueueDisposable
    implements Observer, Runnable {
...
 @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);
            }
        }
@Override
        public void run() {
            if (outputFused) {
                drainFused();
            } else {
                drainNormal();
            }
        }

  void drainNormal() {
          ...
                    a.onNext(v);
          ...
        }
...
final class HandlerScheduler extends Scheduler {
...
 @Override
    public Worker createWorker() {
        return new HandlerWorker(handler, async);
    }
...
}

 private static final class HandlerWorker extends Worker {
        @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, unit.toMillis(delay));
...

果不其然,就是用了handler
总结:链式调用优化了调用方的体验,但是被调用方弯弯绕绕,当然rxjava中有很多值得琢磨的代码点,这里就不赘述了,暂先把总的逻辑问题弄明白吧.

你可能感兴趣的:(RxJava系列(三)--切换线程)