RxJava2 理解:Scheduler

文章目录

  • 一、自定义 Scheduler
  • 二、Scheduler
    • 2.1 Worker
  • 三、Schedulers
  • 四、IoScheduler

一、自定义 Scheduler

public class MySchedulor extends Scheduler {
    @Override
    public Worker createWorker() {
        return null;
    }
}

只有一个方法,createWorker。

那我们创建一个 Worker。

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

class MyWorker extends Worker {

    @Override
    public Disposable schedule(Runnable run, long delay, TimeUnit unit) {
        return null;
    }

    @Override
    public void dispose() {

    }

    @Override
    public boolean isDisposed() {
        return false;
    }
}

Worker 的 schedule 方法用来执行 runnable,我们就直接 run.run()。

@Override
public Disposable schedule(Runnable run, long delay, TimeUnit unit) {
    run.run();
    return null;
}

现在就可以执行 MyScheduler 了。

public static void main(String[] args) {
    MyScheduler myScheduler = new MyScheduler();
    myScheduler.scheduleDirect(new Runnable() {
        @Override
        public void run() {
            System.out.println("hello world");
        }
    });
}

二、Scheduler

一个抽象类,指定了 runnable task 的执行策略。

一个 runnable 任务可以有三种执行方式:

  • 直接执行 scheduleDirect(Runnable)
  • 延迟执行 schedulePeriodicallyDirect(Runnable, long, long, TimeUnit)
  • 间歇执行 scheduleDirect(Runnable, long, TimeUnit)

Scheduler 会有一个或几个 Worker。schedule 的三个方法最终都会通过 Worker 的 schedule 方法执行。

2.1 Worker

一个抽象类,代表 Scheduler 中一个独立的、有序的工作者,用来执行 runnable task。

dispose Worker 时应该取消所有未完成的工作,和运行清除资源

schedule(Runnable)、schedulePeriodically(Runnable, long, long, TimeUnit) 的默认实现委托给了 schedule(Runnable, long, TimeUnit) 抽象方法。

Schedule 的实现最好能去记录每个 runnable task,当他们等待执行的时候,这样可以在 dispose 时可以预防他们的执行或在他们执行时中断他们。

now 的默认实现返回当前时间戳。

schedulePeriodically 的默认实现使用 schedule(Runnable, long, TimeUnit) 去间断性地控制 runnable task。
算法计算下一个 task 应该 run 的时间,然后基于 now() 算出相对时间,去执行它。
但是,系统时间的偏移和修改将会影响到计算结果。因此,默认的实现使用 clockDriftTolerance() 的值去检测 now() 的偏移,然后重新调整相对时间。

如果 Worker 被销毁了,schedule 方法应该返回 Disposables#disposed() 的实例,用来向调用者表示自己的销毁状态。

因为 dispose 可能发生在任何线程,所以如果任务被提交后 dispose 执行了,schedule 的实现应该尽最大的努力去立即取消任务。

所有 Worker 中的方法应该是线程安全的。

他们的关系:

Scheduler 操控 Worker 执行 runnable。

三、Schedulers

Schedulers 类里提供了几个内置的 Scheduler。

public final class Schedulers {
    @NonNull
    static final Scheduler SINGLE;

    @NonNull
    static final Scheduler COMPUTATION;

    @NonNull
    static final Scheduler IO;

    @NonNull
    static final Scheduler TRAMPOLINE;

    @NonNull
    static final Scheduler NEW_THREAD;

    static final class SingleHolder {
        static final Scheduler DEFAULT = new SingleScheduler();
    }

    static final class ComputationHolder {
        static final Scheduler DEFAULT = new ComputationScheduler();
    }

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

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

    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());
    }
    ...
}
  • Schedulers.computation()
    运行计算密集型任务,在一个固定数量的线程池中。大部分异步操作使用它作为默认 Scheduler。
  • Schedulers.io()
    运行 I/O 或者阻塞操作,在一个动态数量的线程池中。
  • Schedulers.single()
    运行在一个单独的线程,顺序执行,先进先出。
  • Schedulers.trampoline()
    运行在当前线程,但不会立即执行,会被放入一个队列,在装配工作完成后顺序执行。
  • Schedulers.newThread()
    在一个新线程上执行任务。

下面以 IO 为例看一下内置 Scheduler 的实现。

四、IoScheduler

static final Scheduler IO;

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

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

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

RxJavaPlugins.initIoScheduler(Callable) 只是进行 hook,如果没有 hook 函数,最终会返回 callable.call()。

上面那一大串最终就相当于:

static final Scheduler IO = new IoScheduler();

写那么多只是为了让 RxJavaPlugins 进行 hook。

IoScheduler 的 createWorker:

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

返回了 EventLoopWorker,看一下 EventLoopWorker 的 schedule 方法:

// EventLoopWorker
public Disposable schedule(@NonNull Runnable action, long delayTime, @NonNull TimeUnit unit) {
    if (tasks.isDisposed()) {
        // don't schedule, we are unsubscribed
        return EmptyDisposable.INSTANCE;
    }

    return threadWorker.scheduleActual(action, delayTime, unit, tasks);
}

schedule 内调了 threadWorker 的 scheduleActual 方法。

// NewThreadWorker
public ScheduledRunnable scheduleActual(...) {
    ...
    if (delayTime <= 0) {
    f = executor.submit((Callable<Object>)sr);
} else {
    f = executor.schedule((Callable<Object>)sr, delayTime, unit);
}
    ...
}

NewThreadWorker 内部通过 ExecutorService 来实际执行 runnable。

你可能感兴趣的:(Android,理解,RxJava,源码)