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");
}
});
}
一个抽象类,指定了 runnable task 的执行策略。
一个 runnable 任务可以有三种执行方式:
Scheduler 会有一个或几个 Worker。schedule 的三个方法最终都会通过 Worker 的 schedule 方法执行。
一个抽象类,代表 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 类里提供了几个内置的 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());
}
...
}
下面以 IO 为例看一下内置 Scheduler 的实现。
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。