Scheduler 调度器
reactor 中提供了一个接口Scheduler 用于线程管理,reactor提供了一个工具类Schedulers来提供现成的调度器。本文从三个地方入手来看调度器的原理
可重用的单线程
Schedulers.newSingle()提供了一个单线程的处理器
public static Scheduler newSingle(String name, boolean daemon) {
return newSingle(new ReactorThreadFactory(name, SingleScheduler.COUNTER, daemon,
true, Schedulers::defaultUncaughtException));
}
public static Scheduler newSingle(ThreadFactory threadFactory) {
final Scheduler fromFactory = factory.newSingle(threadFactory);
fromFactory.start();
return fromFactory;
}
default Scheduler newSingle(ThreadFactory threadFactory) {
return new SingleScheduler(threadFactory);
}
从源码中可以看到,newSingle最后创建了一个 SingleScheduler
SingleScheduler
从代码中可以看出,start方法其实就是创建了一个单线程的线程池然后赋值给了 executor 属性,再来看另一个重要的方法
线程池创建工作对象其实是创建了一个 ExecutorServiceWorker。然后在该worker工作的时候调用的方法
publishOn
publishOn操作符能将部分运行时执行移动到指定的工作单元
Flux.range(1, 3)
.map(i->{
System.out.println("map 在 thread:"+Thread.currentThread().getName());
return i;
})
.publishOn(Schedulers.newSingle("new thread"))
.map(i->{
System.out.println("map2 在 thread:"+Thread.currentThread().getName());
return i;
}).subscribe();
publishOn接受一个Scheduler之后的操作就都会在这个Scheduler提供的线程中执行
public final Flux<T> publishOn(Scheduler scheduler) {
return publishOn(scheduler, Queues.SMALL_BUFFER_SIZE);
}
final Flux<T> publishOn(Scheduler scheduler, boolean delayError, int prefetch, int lowTide) {
return onAssembly(new FluxPublishOn<>(this, scheduler, delayError, prefetch, lowTide, Queues.get(prefetch)));
}
返回的是一个FluxPublishOn, 这是一个 Operator 我们来看看其中源码
我们在之前了解 Operator 原理的时候说过这个 subscriberOrReturn 的作用是包装一个自己的subscriber返回给源头,然后在执行的时候先执行自己的监听者. 所以这里其实是返回了一个监听者
在被当成subscriber的时候其实就是创建了一个队列,然后一口气拉去256个数据,当数据来的时候
先把数据丢到队列中然后调用了一个方法,我们重点看这个方法的逻辑
就是调用了worker的schedule方法,worker我们在上面已经看到了worker里面的原理.所以这个类其实还是一个runnable类.所以我们就看到底是什么方法被丢进了线程池中执行
从源码中我们了解到,方法执行到 FluxPublishOn 的时候就会进入一个线程池开始往下执行.
逻辑图如下
subscribeOn
看完了publishOn再来看看subscribeOn,看懂了publishOn后subscribeOn其实差不多
其实就是在subscribe的时候就已经传入线程池中运行了