1、Scheduler
RxJava是一个为了异步编程而实现的库,默认情况下,RxJava只在当前线程中运行,它是单线程的,此时Observable用于发射数据流,Observer用于接收和响应数据流,各种操作符(Operators)用于加工数据流,实现出来是一个同步的函数响应式。然而响应式的实际应用是大部分操作都在后台处理,前台响应的一个过程。我们可以用RxJava的调度器来实现。
Scheduler | 作用 |
---|---|
single | 定长为1的线程池 |
newThread | 每次启用新线程 |
computation | 固定大小的线程池,大小为CPU核数 |
io | 无数量上限的线程池,可以重用空闲线程 |
trampoline | 直接在当前线程运行,如果当前线程在执行其他任务,会暂停其他任务 |
from | 自定义一个executor来作为调度器 |
Observable.just("aaa", "bbb")
// 线程A
.observeOn(Schedulers.newThread())
.map(String::toUpperCase)
// 线程B
.subscribeOn(Schedulers.single())
// 线程C
.observeOn(Schedulers.io())
.subscribe(System.out::println);
Thread.sleep(1000);
2、线程调度
(1)subscribeOn
指定对数据处理运行在特定的线程调度器Scheduler上
多次执行subscribeOn,只有一次起作用
(2)observeOn
指定下游操作运行在特定的线程调度器Scheduler上
多次执行observeOn,每次都会起作用,线程会一直切换
Observable.just("HELLO WORLD")
// 切换到single
.subscribeOn(Schedulers.single())
.map(String::toLowerCase)
// 切换到io
.observeOn(Schedulers.io())
.map(String::length)
// 这里的切换是无效的
.subscribeOn(Schedulers.computation())
.map(String::valueOf)
// 切换到newThread
.observeOn(Schedulers.newThread())
.subscribe(System.out::println);
3、Scheduler的测试
(1)advanceTimeTo
// advanceTimeTo
// 将调度器的时钟移到某个特定时刻
TestScheduler scheduler = new TestScheduler();
scheduler.createWorker().schedule(() -> System.out.println("now"));
scheduler.createWorker().schedule(() -> System.out.println("10s"), 10, TimeUnit.SECONDS);
scheduler.advanceTimeTo(1, TimeUnit.MILLISECONDS);
// 将指针后移10s
// scheduler.createWorker().schedule(() -> System.out.println("10s"), 10, TimeUnit.SECONDS);会立即执行
scheduler.advanceTimeTo(10, TimeUnit.SECONDS);
System.out.println(scheduler.now(TimeUnit.SECONDS));
(2)advanceTimeBy
// advanceTimeBy
// 将调度程序的时钟按指定的时间向前移动
TestScheduler scheduler = new TestScheduler();
final AtomicInteger atomicInteger = new AtomicInteger(0);
Observable.timer(2, TimeUnit.SECONDS, scheduler).subscribe((v) -> atomicInteger.incrementAndGet());
System.out.println(atomicInteger.get());
scheduler.advanceTimeBy(1, TimeUnit.SECONDS);
System.out.println(atomicInteger.get());
// 时光倒流
scheduler.advanceTimeBy(-1, TimeUnit.SECONDS);
System.out.println(atomicInteger.get());
scheduler.advanceTimeBy(2, TimeUnit.SECONDS);
System.out.println(atomicInteger.get());
(2)triggerActions
// triggerActions
// 不修改时间,执行计划中未启动的任务
TestScheduler scheduler = new TestScheduler();
scheduler
.createWorker()
.schedule(() -> System.out.println("now"));
scheduler
.createWorker()
.schedule(() -> System.out.println("10s"), 10, TimeUnit.SECONDS);
scheduler.triggerActions();