Rxjava线程调度原理

Rxjava 有两个链:1.自下向上调用Observable的subscribe方法,2.自上向下调用Observer的onNext方法。自下向上到ObservableOnSubscribe的subscribe方法,然后开始自上向下。

线程切换是用subscribeOn和observeOn两个方法,它们生成的Observable对象都有Scheduler,Scheduler就是用来帮它们实现线程切换。

了解这两个方法之前介绍下Shedulder

既然要实现线程切换,就一定有地方生成线程,并把需要线程运行的代码封装到Runnable中,让线程运行Runnable,这些都是由Shedulder完成的。

以Schedulers.newThread()为例 介绍下Scheduler,Schedulers.newThread()得到的是NewThreadScheduler。

public Disposable scheduleDirect(@NonNull Runnable run, long delay, @NonNull TimeUnit unit) {
//生成worker,这里的实现类是NewThreadWorker ,里面有个ScheduledExecutorService线程池
 final Worker w = createWorker();

    final Runnable decoratedRun = RxJavaPlugins.onSchedule(run);

    DisposeTask task = new DisposeTask(decoratedRun, w);
//把Runnable 放到线程池执行
    w.schedule(task, delay, unit);

    return task;
}

1.subscribeOn是在自下向上调用subscribe过程中,用scheduler把接下来往上调用的代码放到一个新的线程中,实现线程切换。

一次subscribeOn,表示切换一次线程,如果有多个subscribeOn,再向上不断调用的过程过实现多次线程切换, 只有最靠近Observable.create的subscribeOn,才决定最后ObservableOnSubscribe.subscribe在那个线程执行。

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

//把source.subscribe(parent)的调用封装成Runnable

final class SubscribeTask implements Runnable {
    private final SubscribeOnObserver<T> parent;

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

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

2.observeOn是在Observer自上向下,调用onNext时把接下来调用onNext放到一个子线程执行,所以observeOn影响后面的代码。

observeOn方法生成ObserveOnObserver对象,以下是简要代码

static final class ObserveOnObserver<T> extends BasicIntQueueDisposable<T>
implements Observer<T>, 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();//最终 a.onNext(v);
    }
}
}

3.切换到android 中的主线程 ,AndroidSchedulers.mainThread()生成HandlerScheduler,主要原理还是使用了Android的handler,实现线程切换

// Looper.getMainLooper()表示handler 会在主线程执行
private static final class MainHolder {
    static final Scheduler DEFAULT
        = new HandlerScheduler(new Handler(Looper.getMainLooper()), false);
}
final class HandlerScheduler extends Scheduler{
@Override
public Disposable scheduleDirect(Runnable run, long delay, TimeUnit unit) {
    if (run == null) throw new NullPointerException("run == null");
    if (unit == null) throw new NullPointerException("unit == null");

    run = RxJavaPlugins.onSchedule(run);
    ScheduledRunnable scheduled = new ScheduledRunnable(handler, run);
//把Runnable发送到主线程
    handler.postDelayed(scheduled, unit.toMillis(delay));
    return scheduled;
}

}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值