RxJava原理与自定义操作符-----线程切换原理

7 篇文章 0 订阅

RxJava称为响应式编程
RxJava也称为异步事件流编程
线程的切换很重要

一.subscribeOn 给上面代码分配线程

                .subscribeOn(
     
                        Schedulers.io() // 耗时读取的异步

    
                )

1.先分析Schedulers.io() 和它的hook

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

return RxJavaPlugins.onIoScheduler(IO); 又是一个hook

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

查看 onIoHandler 唯一被赋值的地方:

    public static void setIoSchedulerHandler(@Nullable Function<? super Scheduler, ? extends Scheduler> handler) {
        if (lockdown) {
            throw new IllegalStateException("Plugins can't be changed anymore");
        }
        onIoHandler = handler;
    }

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:

    @NonNull
    static final Scheduler IO;
    static {
        SINGLE = RxJavaPlugins.initSingleScheduler(new SingleTask());

        COMPUTATION = RxJavaPlugins.initComputationScheduler(new ComputationTask());

        IO = RxJavaPlugins.initIoScheduler(new IOTask());

        TRAMPOLINE = TrampolineScheduler.instance();

        NEW_THREAD = RxJavaPlugins.initNewThreadScheduler(new NewThreadTask());
    }

IO = RxJavaPlugins.initIoScheduler(new IOTask());
IO 的实例化中又来了hook:

    @NonNull
    public static Scheduler initIoScheduler(@NonNull Callable<Scheduler> defaultScheduler) {
        ObjectHelper.requireNonNull(defaultScheduler, "Scheduler Callable can't be null");
        Function<? super Callable<Scheduler>, ? extends Scheduler> f = onInitIoHandler;
        if (f == null) {
            return callRequireNonNull(defaultScheduler);
        }
        return applyRequireNonNull(f, defaultScheduler);
    }

onInitIoHandler 只有一个地方可以赋值:

    public static void setInitIoSchedulerHandler(@Nullable Function<? super Callable<Scheduler>, ? extends Scheduler> handler) {
        if (lockdown) {
            throw new IllegalStateException("Plugins can't be changed anymore");
        }
        onInitIoHandler = handler;
    }

hook代码:

        // TODO hook 给 IO 初始化
        RxJavaPlugins.setInitIoSchedulerHandler(new Function<Callable<Scheduler>, Scheduler>() {
            @Override
            public Scheduler apply(Callable<Scheduler> schedulerCallable) throws Exception {
                Log.d(L.TAG, "apply: 全局监听 init scheduler:" +schedulerCallable.call());
                return schedulerCallable.call();
            }
        });

2.第一步分析 .io() 和 .newThread()

Schedulers.io() 一执行 返回的就是Scheduler IO;

IO = RxJavaPlugins.initIoScheduler(new IOTask());

new IOTask()

Schedulers 策略机制 IO是一种
Schedulers 策略最终用线程池完成
策略:
Schedulers.io() : 耗时读取的异步
Schedulers.newThread() : 开启新线程异步

Schedulers.io() 耗时读取的异步策略 是用 new IOTask() 完成的
Schedulers.newThread() 开启新线程异步 是用 new NewThreadTask() 完成的

查看IOTask:

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

静态内部类,实现了Callable,有返回值的任务

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

返回一个IoScheduler()
查看IoScheduler()

    public IoScheduler() {
        this(WORKER_THREAD_FACTORY);
    }
    public IoScheduler(ThreadFactory threadFactory) {
        this.threadFactory = threadFactory;
        this.pool = new AtomicReference<CachedWorkerPool>(NONE);
        start();
    }
    @Override
    public void start() {
        CachedWorkerPool update = new CachedWorkerPool(KEEP_ALIVE_TIME, KEEP_ALIVE_UNIT, threadFactory);
        if (!pool.compareAndSet(NONE, update)) {
            update.shutdown();
        }
    }
        void shutdown() {
            allWorkers.dispose();
            if (evictorTask != null) {
                evictorTask.cancel(true);
            }
            if (evictorService != null) {
                evictorService.shutdownNow();
            }
        }
        private final ScheduledExecutorService evictorService;

线程池

public interface ScheduledExecutorService extends ExecutorService {...}
        .subscribeOn(

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

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

        )

查看NewThreadTask:

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

静态内部类,实现了Callable,有返回值的任务

    static final class NewThreadHolder {
        static final Scheduler DEFAULT = new NewThreadScheduler();
    }

返回一个NewThreadScheduler()
在这里插入图片描述

3.第二步分析.subscribeOn()

IoScheduler()传进去

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

IoScheduler()存在这里

    final Scheduler scheduler;

    public ObservableSubscribeOn(ObservableSource<T> source, Scheduler scheduler) {
        super(source);
        this.scheduler = scheduler;
    }
        // ObservbaleCreate.subscribeOn
        // TODO 第二步     new IOScheduler ---> 线程池 传递进去
        .subscribeOn(

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

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

        )

         // A线程. subscribe
         //  ObservableSubscribeOn.subscribe
        .subscribe(自定义观察者);

ObservableSubscribeOn.subscribe()
进入到ObservableSubscribeOn的subscribeActual函数中
s是终点 包装成SubscribeOnObserver包裹1

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

parent就是我们的包裹1
SubscribeTask 任务给线程池运行的

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

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

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

在任务的run当中source.subscribe(parent);
调用了ObservableCreate里面的CreateEmitter封装成包裹2

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

source.subscribe(parent); 自定义source

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

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

final Scheduler scheduler = IoScheduler(线程池的)
ObservableSubscribeOn 里面的subscribeActual

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

scheduler.scheduleDirect(new SubscribeTask(parent))
IoScheduler(线程池的).scheduleDirect(new SubscribeTask(parent))
scheduleDirect函数:

    @NonNull
    public Disposable scheduleDirect(@NonNull Runnable run) {
        return scheduleDirect(run, 0L, TimeUnit.NANOSECONDS);
    }
    @NonNull
    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;
    }
   @NonNull
    public abstract Worker createWorker();

createWorker的创建丢给子类
IoScheduler.createWorker(){new EventLoopWorker(pool.get();}
查看其在IoScheduler里面的子类

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

把EventLoopWorker类创建出来
继续查看抽象类Scheduler的scheduleDirect

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

decoratedRun就是红色的Runnable
交给DisposeTask任务,其又是一个Runnable 做到中断

    static final class DisposeTask implements Runnable, Disposable {
        final Runnable decoratedRun;
        final Worker w;

        Thread runner;

        DisposeTask(Runnable decoratedRun, Worker w) {
            this.decoratedRun = decoratedRun;
            this.w = w;
        }
        ...
}

把最后封装好的Runnable 丢给w
w是new EventLoopWorker(pool.get(); new好的对象
w.schedule(task, delay, unit); 就调用到EventLoopWorker类里面的schedule去了

        @NonNull
        @Override
        public Disposable schedule(@NonNull Runnable action) {
            if (disposed) {
                return EmptyDisposable.INSTANCE;
            }

            return poolWorker.scheduleActual(action, 0, TimeUnit.MILLISECONDS, serial);
        }

又丢给scheduleActual

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

executor.submit((Callable)sr) 最后丢给了线程池

parent.setDisposable(scheduler.scheduleDirect(new SubscribeTask(parent)));

SubscribeTask(parent)任务一执行就会处于异步
整块都是异步
source 异步线程

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

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

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

自定义观察者中的onSubscribe是不参与线程转换的,还是主线程

                            @Override
                            public void onSubscribe(Disposable d) {

                                Disposable disposable = d;
                            }

终点是不能是异步线程的,我们要在终点更新UI ↓
在这里插入图片描述

二.observeOn 给下面代码分配线程

                // TODO 第二步骤
                .observeOn(

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

                )

1.第一步分析 AndroidSchedulers.mainThread()

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

最后是通过handler切换主线程的
new Handler(Looper.getMainLooper()) Looper放进去保证100%一定是主线程
传进去的handler100%主线程

    private final Handler handler;

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

HandlerScheduler的createWorker

    @Override
    public Worker createWorker() {
        return new HandlerWorker(handler);
    }

然后就是HandlerScheduler$.HandlerWorker
HandlerScheduler的内部类HandlerWorker

schedule{
	......
	handler.sendMessageDelayed(message, Math.max(0L, unit.toMillis(delay)));
	......
}

AndroidSchedulers.mainThread()
这一句话就是拿到了主线程的handler

在这里插入图片描述

2.第二步分析 .observeOn()

    @CheckReturnValue
    @SchedulerSupport(SchedulerSupport.CUSTOM)
    public final Observable<T> observeOn(Scheduler scheduler) {
        return observeOn(scheduler, false, bufferSize());
    }
    @CheckReturnValue
    @SchedulerSupport(SchedulerSupport.CUSTOM)
    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));
    }

scheduler 是主线程handler的 scheduler
查看ObservableObserveOn

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

ObservableObserveOn里面存放一份主线程handler的scheduler

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

if (scheduler instanceof TrampolineScheduler)
如果线程相同则不用干活
如果线程不同就先打包裹
new ObserveOnObserver(observer, w, delayError, bufferSize)

订阅是observeOn()返回的类ObservableObserveOn点出来的
ObservableObserveOn.subscribe
在ObservableObserveOn里面的subscribeActual函数里面打包第一个包裹1 ObserveOnObserver
在上一层是ObservableCreate

最后返回到ObserveOnObserver里面的onNext是会把任务交给handler

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

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

schedule();之上是子线程,schedule();执行后就交给handler变成主线程了

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

逻辑图

在这里插入图片描述
subscribeOn()切换线程时序图
在这里插入图片描述
observeOn()时序图
在这里插入图片描述
Scheduler分类
在这里插入图片描述
补充

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

                // observeOn(A)
                // observeOn(B)
                // observeOn(C) // 终点是被C执行
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值