Scheduler翻译成中文就是“调度”的意思,在RxJava里就是线程之间的调度,也就是线程之间的切换。
从图中可以简单看出,SingleScheduler、ComputationScheduler、IoScheduler、NewThreadScheduler的核心实现就是一个线程池,但该线程池里只会有一个线程,而newScheduledThreadPool是可以延迟、定时执行的,所以我们可以认为SingleScheduler、ComputationScheduler、IoScheduler、NewThreadScheduler的核心实现就是一个可定时、可延迟执行及轮询的特殊线程,下面简称线程。该线程是通过Observable的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;
}
createWorker
是一个抽象的方法,在SingleScheduler、ComputationScheduler、IoScheduler、NewThreadScheduler中分别有不同的实现。
1、SingleScheduler原理分析
createWorker在SingleScheduler中的实现如下,在调用ScheduledWorker的schedule方法将任务交给线程执行。
public Worker createWorker() {
//传入一个有且只有一个线程的线程池,就是上面说的特殊线程
return new ScheduledWorker(executor.get());
}
public Disposable schedule(@NonNull Runnable run, long delay, @NonNull TimeUnit unit) {
...
tasks.add(sr);
try {
Future<?> f;
//将任务交给线程执行
if (delay <= 0L) {
f = executor.submit((Callable<Object>)sr);
} else {
f = executor.schedule((Callable<Object>)sr, delay, unit);
}
sr.setFuture(f);
} catch (RejectedExecutionException ex) {
...
}
SingleScheduler的原理比较简单,到此就完毕了。但线程是在那里创建的尼?其实在SingleScheduler的构造方法就已经创建了线程。由于SingleScheduler是单例实现,所有SingleScheduler中有且仅有一个线程。 那么当多任务且有耗时操作时,后面的任务就会等待。
public SingleScheduler(ThreadFactory threadFactory) {
this.threadFactory = threadFactory;
executor.lazySet(createExecutor(threadFactory));
}
//创建线程池
static ScheduledExecutorService createExecutor(ThreadFactory threadFactory) {
return SchedulerPoolFactory.create(threadFactory);
}
//是SchedulerPoolFactory中的create方法
public static ScheduledExecutorService create(ThreadFactory factory) {
//创建线程池
final ScheduledExecutorService exec = Executors.newScheduledThreadPool(1, factory);
tryPutIntoPool(PURGE_ENABLED, exec);
return exec;
}
2、ComputationScheduler原理分析
ComputationScheduler就比较麻烦一点了,图中可以看出ComputationScheduler里创建了一组线程。也是在构造方法中创建的,构造方法中调用start方法。
public ComputationScheduler(ThreadFactory threadFactory) {
this.threadFactory = threadFactory;
this.pool = new AtomicReference<FixedSchedulerPool>(NONE);
start();
}
public void start() {
//MAX_THREADS = cap(Runtime.getRuntime().availableProcessors(), Integer.getInteger(KEY_MAX_THREADS, 0));
FixedSchedulerPool update = new FixedSchedulerPool(MAX_THREADS, threadFactory);
//用update替代默认的NONE,NONE中没有任何线程创建
if (!pool.compareAndSet(NONE, update)) {
update.shutdown();
}
}
在start中创建了FixedSchedulerPool
对象,其中MAX_THREADS是根据Runtime.getRuntime().availableProcessors()
计算出来的。来看一下FixedSchedulerPool
对象的实现
static final class FixedSchedulerPool implements SchedulerMultiWorkerSupport {
final int cores;
final PoolWorker[] eventLoops;
long n;
FixedSchedulerPool(int maxThreads, ThreadFactory threadFactory) {
// initialize event loops
this.cores = maxThreads;
this.eventLoops = new PoolWorker[maxThreads];
//每个PoolWorker代表一个Executors.newScheduledThreadPool(1, factory)的实现
for (int i = 0; i < maxThreads; i++) {
this.eventLoops[i] = new PoolWorker(threadFactory);
}
}
//eventLoops中取出一个线程
public PoolWorker getEventLoop() {
int c = cores;
if (c == 0) {
return SHUTDOWN_WORKER;
}
// simple round robin, improvements to come
return eventLoops[(int)(n++ % c)];
}
...
@Override
public void createWorkers(int number, WorkerCallback callback) {
int c = cores;
if (c == 0) {
for (int i = 0; i < number; i++) {
callback.onWorker(i, SHUTDOWN_WORKER);
}
} else {
int index = (