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();