Rxjava(3) 執行緒切換 - Schedulers.io()

木木___發表於2020-04-02

observable的.subscribeOn(Schedulers.io())方法是指定處理的事件流在哪個執行緒中執行

Schedulers:對外提供獲取的方法
IOTask:統一task的建立方式
Scheduler:統一呼叫的api,IoScheduler/ComputationScheduler/NewThreadScheduler均為繼承類。
Scheduler.Worker:管理具體執行的任務。

時序圖

1, 改用該方法後,建立了ObservableSubscribeOn物件,將上層的observable進行包裝代理和傳入的Scheduler進行儲存。

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

複製程式碼

2, 然後會執行到ObservableSubscribeOn的subscribeActual方法,在(1)中的時候寫過這個流程。在這個方法中,核心程式碼是第三句。

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

    @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)));
    }
複製程式碼

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

在這行語句中 scheduler是處理runable的執行緒池,就是傳過來的Schedulers.io()物件。 SubscribeTask是個Runnable

執行緒池執行runable的run方法。 source是上層的observable parent是對下層包裝的observer

    final class SubscribeTask implements Runnable {
        private final SubscribeOnObserver<T> parent;
        SubscribeTask(SubscribeOnObserver<T> parent) {
            this.parent = parent;
        }
        public void run() {
            source.subscribe(parent);
        }
    }
}

複製程式碼

最終的結果會呼叫到SubscribeOnObserver的onNext中。

    static final class SubscribeOnObserver<T> extends AtomicReference<Disposable> implements Observer<T>, Disposable {
        final Observer<? super T> actual;

        final AtomicReference<Disposable> s;

        SubscribeOnObserver(Observer<? super T> actual) {
            this.actual = actual;
            this.s = new AtomicReference<Disposable>();
        }
 
        @Override
        public void onNext(T t) {
            actual.onNext(t);
        }
     }
複製程式碼

4, Schedulers.io()的準備工作

IO 的賦值的是在靜態程式碼塊中初始化。

    public static Scheduler io() {
        return RxJavaPlugins.onIoScheduler(IO);
    }
    
     static {
 // 通過這個方法 呼叫  IOTask中的call 返回   new IoScheduler() 物件
        IO = RxJavaPlugins.initIoScheduler(new IOTask());
    }
複製程式碼

5, IoScheduler繼承Scheduler。並且實現了Scheduler的抽象方法createWorker。


    @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;
    }
複製程式碼

6, 在 IoScheduler的createWorker方法中建立了EventLoopWorker物件。所以在w.schedule是呼叫的EventLoopWorker中的schedule方法。

    @Override
    public Worker createWorker() {
        return new EventLoopWorker(pool.get());
    }
複製程式碼
    static final class EventLoopWorker extends Scheduler.Worker {
        private final CompositeDisposable tasks;
        private final CachedWorkerPool pool;
        private final ThreadWorker threadWorker;

        EventLoopWorker(CachedWorkerPool pool) {
            this.pool = pool;
            this.tasks = new CompositeDisposable();
            this.threadWorker = pool.get();
        }
        @Override
        public Disposable schedule(@NonNull Runnable action, long delayTime, @NonNull TimeUnit unit) {
            if (tasks.isDisposed()) {
                return EmptyDisposable.INSTANCE;
            }
            return threadWorker.scheduleActual(action, delayTime, unit, tasks);
        }
    }
複製程式碼

7, ThreadWorker執行緒工作類,繼承NewThreadWorker,scheduleActual在NewThreadWorker中。

    static final class ThreadWorker extends NewThreadWorker {
        private long expirationTime;

        ThreadWorker(ThreadFactory threadFactory) {
            super(threadFactory);
            this.expirationTime = 0L;
        }

        public long getExpirationTime() {
            return expirationTime;
        }

        public void setExpirationTime(long expirationTime) {
            this.expirationTime = expirationTime;
        }
    }
複製程式碼

8, 在這裡看到executor.schedule,呼叫執行緒池執行runable的地方。runable方法一直傳遞到這裡。

 @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;
    }
複製程式碼

類圖

Rxjava(3)  執行緒切換 - Schedulers.io()

相關文章