RxJava2.0- Schedulers线程切换原理分析

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/fengluoye2012/article/details/79230298
简介
RxJava的核心是异步;Schedulers实现发射和接收事件在两种不同的线程中去执行相应的操作;  调度器(Schedulers )是RxJava中最重要的一部分,随意的切换调用线程;
Schedulers在RxJava中主要有一下几种方式:
SingleScheduler:共享的,单一线程的调度器;内部有一个核心线程数为1,最大线程数为Integer.MAX的线程池;
ComputationScheduler:计算调度器;内部有一个固定线程池,大小为 CPU 核数;
IoScheduler:Io调度器;内部有一个核心线程数为1,最大线程数为Integer.MAX的线程池;60s的保活时间,保活时间可重复利用;
 NewThreadScheduler:新线程调度器;每次都开启一个新线程执行任务;内部有一个核心线程数为1,最大线程数为Integer.MAX的线程池;
TrampolineScheduler:默认情况下,工作在默认的线程;在那个线程发送事件,就在那个线程接收事件,调用不会立即执行,加入队列中,依次执行;
AndroidSchedulers.mainThread():运行在主线程中;通过Handler切换线程;
用法
通过subscribeOn()和observeOn()改变发射事件和接收事件的线程;
Observable.create(new ObservableOnSubscribe<String>() {
  @Override
  public void subscribe(@NonNull ObservableEmitter<String> emitter) throws Exception {
    Log.e(tag, Thread.currentThread().getName());
    for (int i = 0; i < 10; i++) {
      emitter.onNext("hello");
      Log.e(tag, "newThread() 发送" + Thread.currentThread().getName());
    }
  }
 }).subscribeOn(Schedulers.newThread())
  .observeOn(AndroidSchedulers.mainThread())
  .subscribe(new Consumer<String>() {
  @Override
  public void accept(String s) throws Exception {
    Log.e(tag, "接收::" + Thread.currentThread().getName());
    Log.e(tag, s);
  }
});
Schedulers线程切换的原理
以上面的代码来分析:
大概的顺序:
1)初始化顺序:ObservableCreate--ObservableSubscribeOn-ObservableObserveOn-LambdaObserver完成初始化;
2)实际的订阅顺序:
2.1)ObservableObserveOn类中的subscribeActual()方法中,创建工作线;ObservableObserveOn订阅(subscribe)ObservableObserveOn类中匿名ObserveOnObserver类,并且将LambdaObserver实例作为参数,传入ObserveOnObserver构造函数;
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));//ObservableObserveOn订阅ObserveOnObserver,并LambdaObserver实例observer
  }
}
2.2)在ObservableSubscribeOn类中的subscribeActual方法中,ObserveOnObserver调用onSubscribe()方法,在此方法中LambdaObserver调用onSubscribe(),在此方法中Consumer调用accept(this);
并且在ObservableSubscribeOn类中的subscribeActual中创建task;
ObservableSubscribeOn类,发送事件切换线程的实现过程
@Override
public void subscribeActual(final Observer<? super T> s) {
  final SubscribeOnObserver<T> parent = new SubscribeOnObserver<T>(s);//创建,并传入ObservableObserveOn类的匿名类ObserveOnObserver
  s.onSubscribe(parent);//ObserveOnObserver调用onSubscribe(方法)
  parent.setDisposable(scheduler.scheduleDirect(new SubscribeTask(parent)));//创建SubscribeTask,切换线程,切换到subscribeOn()中指定的线程;
}
scheduleDirect()方法:在调度任务器上调度给定的任务,支持多线程访问;
@NonNull
public Disposable scheduleDirect(@NonNull Runnable run) {
  return scheduleDirect(run, 0L, TimeUnit.NANOSECONDS);
}
scheduleDirect():执行延时任务
@NonNull
public Disposable scheduleDirect(@NonNull Runnable run, long delay, @NonNull TimeUnit unit) {
  //Worker抽象类,连续的调度器为了在单个线程或事件循环中执行操作
  final Worker w = createWorker();
  final Runnable decoratedRun = RxJavaPlugins.onSchedule(run);//onSchedule()方法当task被调度的时候调用
  DisposeTask task = new DisposeTask(decoratedRun, w);//相当于一个Runnable,调用decoratedRun的run()方法
  w.schedule(task, delay, unit);
  return task;
}
NewThreadScheduler类中的createWorker()方法,
public Worker createWorker() {
  return new NewThreadWorker(threadFactory);//NewThreadWorker()方法创建一个线程池
}
NewThreadWorker的schedule()方法
@NonNull
@Override
public Disposable schedule(@NonNull final Runnable run) {
  return schedule(run, 0, null);
}
@NonNull
@Override
public Disposable schedule(@NonNull final Runnable action, long delayTime, @NonNull TimeUnit unit) {
  if (disposed) {
    return EmptyDisposable.INSTANCE;
  }
  return scheduleActual(action, delayTime, unit, null);
}
scheduleActual()把给定的Runnable包装成ScheduledRunnable;并且在线程池调用;
@NonNull
public ScheduledRunnable scheduleActual(final Runnable run, long delayTime, @NonNull TimeUnit unit, @Nullable DisposableContainer parent) {
  Runnable decoratedRun = RxJavaPlugins.onSchedule(run);//当Task被调度的时候调用
  ScheduledRunnable sr = new ScheduledRunnable(decoratedRun, parent);//把给定的Runnable包装成ScheduledRunnable
  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;
}
发送事件切换线程原理总结:在subscribeActual()方法中创建SubscribeTask,传入scheduleDirect()方法中,在scheduleDirect()调用指定线程的的createWorker()方法,调用NewThreadWorker类创建线程池;worker调用schedule()方法,在schedule()中调用scheduleActual(),在scheduleActual()把给定的Runnable包装成ScheduledRunnable;并且在线程池调用;
在ObservableObserveOn类匿名类ObserveOnObserver的onSubscribe()
@Override
public void onSubscribe(Disposable s) {
  //省略中间部分   
  actual.onSubscribe(this);//LambdaObserver调用onSubscribe(),在此方法中Consumer调用accept(this)
}
 SubscribeTask类:ObservableObserveOn的匿名类内部类
final class SubscribeTask implements Runnable {
  private final SubscribeOnObserver<T> parent;

  SubscribeTask(SubscribeOnObserver<T> parent) {
    this.parent = parent;
  }
  @Override
  public void run() {
    source.subscribe(parent);//ObservableCreate订阅ObservableSubscribeOn类SubscribeOnObserver
  }
}
2.3)ObservableCreate类中subscribeActual()方法中source.subscribe(parent):当前类Observable订阅ObservableCreate类中CreateEmitter;
ObservableCreate类
@Override
protected void subscribeActual(Observer<? super T> observer) {
  CreateEmitter<T> parent = new CreateEmitter<T>(observer);//实例化,传入ObservableSubscribeOn类SubscribeOnObserver
  observer.onSubscribe(parent);//SubscribeOnObserver执行onSubscribe
  try {
    source.subscribe(parent);//ObservableOnSubscribe订阅CreateEmitter
  } catch (Throwable ex) {
    Exceptions.throwIfFatal(ex);
    parent.onError(ex);
  }
}
subscribe():从写法上看是被观察者订阅观察者;只是为了链式写法方便;实际上是观察者订阅被观察者;从上面的分析可以看出来;订阅顺序是倒叙订阅;
3)发射事件和接收事件
ObservableEmitter发送事件;
4)接收事件顺序
onNext()方法执行顺序:ObservableCreate类中匿名类CreateEmitter类--ObservableSubscribeOn类中匿名类ObserveOnObserver--ObservableObserveOn类匿名内部类ObserveOnObserver--LambdaObserver--onNext.accept(t);
即:调用ObservableCreate类中匿名类CreateEmitter的onNext()方法,中调用ObservableSubscribeOn类中匿名类ObserveOnObserver的onNext()方法;然后调用ObservableObserveOn类匿名内部类ObserveOnObserver的onNext();然后调用LambdaObserver类中的onNext()方法,在LambdaObserver方法中调用onNext.accept(t),接收事件;
从上面的分析:相关的操作符都是通过订阅关系、接收事件的循环实现各种操作符需要的效果;
在ObservableSubscribeOn切换到指定线程发送事件;如何将切换到指定线程接收事件呢?
ObservableObserveOn类subscribeActual()方法
@Override
protected void subscribeActual(Observer<? super T> observer) {
  if (scheduler instanceof TrampolineScheduler) {//默认情况下,在那个线程发送事件,就在那个线程接收事件
    source.subscribe(observer);
  } else {
    Scheduler.Worker w = scheduler.createWorker();//调用的是HandlerScheduler的实现方法createWorker(),创建HandlerWorker实例;
    source.subscribe(new ObserveOnObserver<T>(observer, w, delayError, bufferSize));
  }
}
HandlerScheduler内部创建Handler;
看下ObservableObserveOn类匿名内部类ObserveOnObserver类中onNext()方法;
@Override
public void onNext(T t) {
  if (done) {
    return;
  }
  if (sourceMode != QueueDisposable.ASYNC) {
    queue.offer(t);
  }
  schedule();
}
再看下schedule()方法;安排一个Runnable来执行,就是observeOn()指定的线程;
void schedule() {
  if (getAndIncrement() == 0) {
    worker.schedule(this);
  }
}
schedule()方法
@NonNull
public Disposable schedule(@NonNull Runnable run) {
  return schedule(run, 0L, TimeUnit.NANOSECONDS);
}
HandlerWorker是HandlerScheduler的内部类,继承了Worker类;看下其内部的schedule()实现方法;把给定的Runnable包装成
ScheduledRunnable,然后发送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);//把给定的Runnable包装成ScheduledRunnable
  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)));//发送Handler消息
  if (disposed) {
    handler.removeCallbacks(scheduled);
    return Disposables.disposed();
  }
  return scheduled;
}
接收事件切换线程的原理总结:创建指定线程的Worker实例,调用schedule()方法,在具体的Worker实现类中调用schedule()方法,在此方法中把给定的Runnable包装成ScheduledRunnable,发送Handler消息或者线程池调用;
借用一张图来总结来自http://blog.csdn.net/u011291205/article/details/73044256,可以很好的总结上面的分析内容;
以上就是Schedulers原理实现的全部流程,可自行断点跟踪;如有问题,请多指教!
参考文档

猜你喜欢

转载自blog.csdn.net/fengluoye2012/article/details/79230298