RxJava源码(线程)

RxJava源码(从 just 开始)

RxJava源码(简单操作符)

RxJava源码(线程)

RxJava源码(背压)

RxJava源码(RxBinding)

RxJava源码(衍生 RxLifecycle)

RxJava github 地址:https://github.com/ReactiveX/RxJava/tree/2.x

RxJava 相关概念和一些用法这里不再赘述,可以查看官方文档 官方文档 以及其他的一些博客,闲话少说,这里直接从 rx 的 github 中简单用法去深入源码解读。

这篇分析 rx 的线程切换,废话不多说,直接上代码

        val currentTimeMillis = System.currentTimeMillis()
        Flowable.fromCallable<Any> {
            println("时间间隔:" + (System.currentTimeMillis() - currentTimeMillis) + " , 所在线程:" + Thread.currentThread())
            Thread.sleep(1000) //  imitate expensive computation
            println("时间间隔:" + (System.currentTimeMillis() - currentTimeMillis) + " , 所在线程:" + Thread.currentThread())
            "Done"
        }
                .subscribeOn(Schedulers.io())
                .observeOn(Schedulers.single())
                .subscribe({ x: Any? ->
                    println("时间间隔:" + (System.currentTimeMillis() - currentTimeMillis) + " , 所在线程:" + Thread.currentThread())
                    println(x)
                }) { obj: Throwable ->
                    obj.printStackTrace()
                }

这段代码会输出什么呢?

 时间间隔:41 , 所在线程:Thread[RxCachedThreadScheduler-1,5,main]
 时间间隔:1042 , 所在线程:Thread[RxCachedThreadScheduler-1,5,main]
 时间间隔:1043 , 所在线程:Thread[RxSingleScheduler-1,5,main]
 Done

为什么 fromCallable 在 Cached 线程,而打印却在 Single 线程呢?进入源码先看下 subscribeOn

首先了解下 Schedulers.io()

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

IO 在静态代码块中初始化,如下 

    static final Scheduler IO;

    static {
        //
        //走IOTask的回调
        IO = RxJavaPlugins.initIoScheduler(new IOTask());
        
        //
    }

调用到 IOTask


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

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

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

IoScheduler 的 start 中调用 Executors.newScheduledThreadPool(1, EVICTOR_THREAD_FACTORY); 创建了线程池

Schedulers.single() 同理,不过创建的线程池不一样,这里不追究下去。因此便有了 IO 和 SINGLE 两种线程池。

接下来查看 subscribeOn

    public final Flowable<T> subscribeOn(@NonNull Scheduler scheduler) {
        ObjectHelper.requireNonNull(scheduler, "scheduler is null");
        return subscribeOn(scheduler, !(this instanceof FlowableCreate));
    }

    public final Flowable<T> subscribeOn(@NonNull Scheduler scheduler, boolean requestOn) {
        ObjectHelper.requireNonNull(scheduler, "scheduler is null");
        return RxJavaPlugins.onAssembly(new FlowableSubscribeOn<T>(this, scheduler, requestOn));
    }

将有 IO 线程池的 scheduler 传入,并且判断之前创建的 Flowable 是否为 FlowableCreate,将三个参数封装成 FlowableSubscribeOn 对象内。

同理,observeOn 中将由 SINGLE 线程池的 scheduler 封装成 FlowableObserveOn。

我们直接看 FlowableObserveOn 的 subscribeActual 方法做了什么

    public void subscribeActual(Subscriber<? super T> s) {
        Worker worker = scheduler.createWorker();

        if (s instanceof ConditionalSubscriber) {
            source.subscribe(new ObserveOnConditionalSubscriber<T>(
                    (ConditionalSubscriber<? super T>) s, worker, delayError, prefetch));
        } else {
            source.subscribe(new ObserveOnSubscriber<T>(s, worker, delayError, prefetch));
        }
    }

这里第一行的 createWorker 方法与之前的操作符不同了,重点关注下,它是个接口

    public Worker createWorker() {
        return new ScheduledWorker(executor.get());
    }

创建了对象那个 ScheduledWorker,它也是个 Disposable。

将参数 ScheduledWorker 封装成为 ObserveOnSubscriber ,并使用 LambdaSubscriber 订阅。

FlowableSubscribeOn 的 subscribeActual 方法

    public void subscribeActual(final Subscriber<? super T> s) {
        Scheduler.Worker w = scheduler.createWorker();
        final SubscribeOnSubscriber<T> sos = new SubscribeOnSubscriber<T>(s, w, source, nonScheduledRequests);
        s.onSubscribe(sos);

        w.schedule(sos);
    }

 首先,第一行代码中,FlowableSubscribeOn 创建了 EventLoopWorker

    public Worker createWorker() {
        return new EventLoopWorker(pool.get());
    }

第二行,将参数封装到 SubscribeOnSubscriber 中。

第三行,onSubscribe 意味着 subscribeOn 与上两篇创建性操作符 just、range 有些类似了,要开始创建数据了。但是它没有数据源呀,带着疑问继续。

经过上篇分析,自然到了最下面创建的 FlowableObserveOn 的内部类 ObserveOnSubscriber 或父类中的 request 方法

        public final void request(long n) {
            if (SubscriptionHelper.validate(n)) {
                BackpressureHelper.add(requested, n);
                trySchedule();
            }
        }

        final void trySchedule() {
            if (getAndIncrement() != 0) {
                return;
            }
            worker.schedule(this);
        }

这边调用 SINGLE 创建出来的 ScheduledWorker 的 schedule 方法,将自身 ObserveOnSubscriber (实现也实现了 Runnable )传进入。

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

    public Disposable schedule(@NonNull Runnable run, long delay, @NonNull TimeUnit unit) {
            //判断
            //Hook
//
                    f = executor.submit((Callable<Object>)sr);
           //
        }

将 ObserveOnSubscriber 加到 SINGLE 线程池中了

第四行代码,调用 IO 创建出来的 ScheduledWorker 的 schedule 方法,将自身SubscribeOnSubscriber(也实现了 Runnable )传进入,自然也是加入线程池。

先看下 ObserveOnSubscriber 的 run

void runAsync() {
            final Subscriber<? super T> a = downstream;
            final SimpleQueue<T> q = queue;
            for (;;) {
                long r = requested.get();
                while (e != r) {
                    boolean d = done;
                    T v;
                    try {
                        v = q.poll();
                    } catch (Throwable ex) {
                    }
                    boolean empty = v == null;
                    if (empty) {
                        break;
                    }
                    a.onNext(v);
                    e++;
                    if (e == limit) {
                        if (r != Long.MAX_VALUE) {
                            r = requested.addAndGet(-e);
                        }
                        upstream.request(e);
                        e = 0L;
                    }
                }
                
            }
        }

可以看到初始化了 SimpleQueue ,之后 v = q.poll(),阻塞等待。这里如果数据发射在 

SubscribeOnSubscriber 的 run

        public void run() {
            lazySet(Thread.currentThread());
            Publisher<T> src = source;
            source = null;
            src.subscribe(this);
        }

将 FlowableSubscribeOn 初始化时候传进的 Flowable.fromCallable 赋值给 src,之后订阅我们的事件,所以我们的事件触发在IO线程。经过 FlowableFromCallable 的 callable.call(),依次传递,之后调用 SubscribeOnSubscriber 的 onNext,如下,这里 downstream 自然是 ObserveOnSubscriber 。

        @Override        
        public void onNext(T t) {
            downstream.onNext(t);
        }

ObserveOnSubscriber 中,它的 onComplete 方法如下

        @Override        
        public final void onNext(T t) {
            //判断
            trySchedule();
        }

 trySchedule 方法又将启动 SINGLE 线程,和之前 ObserveOnSubscriber 的 run 一直。这次可以取得数据,并执行 a.onNext(v),这里的 a 即 LambdaSubscriber,即我们自己的 Consumer。

如果我们创建多个 subscribeOn,那么数据发射会在哪个线程?自然,是最上层的线程了。

而创建多个 observeOn 则不同,每次都需要发送到 observeOn 创建的线程中。

最后看下 rxandroid 中的 AndroidSchedulers

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

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

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

它则创建 HandlerScheduler 对象,内部创建 HandlerWorker,schedule 方法则是将 runnable 交给主线程的 handler 处理,附上代码

        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.

            if (async) {
                message.setAsynchronous(true);
            }

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

            //

            return scheduled;
        }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值