RxJava2 - interval and schedulers

心已入冬 提交于 2021-01-28 18:58:43

问题


Let's say I have an interval, and that I've given it a computationScheduler. Like this:

Observable
    .interval(0, 1, TimeUnit.SECONDS, computationScheduler)
    .flatMap { ... }

Then, will everything that happens in flatmap {...} also be scheduled on a computation thread?

In the sources for Observable.interval(long initialDelay, long period, TimeUnit unit, Scheduler scheduler), it says:

 * @param scheduler
 * the Scheduler on which the waiting happens and items are emitted

As a beginner to RxJava, I'm having a hard time understanding this comment. I understand that the interval timer/waiting logic occurs on the computation thread. But, does the last part, about items being emitted, also mean that the emitted items will be consumed on the same thread? Or is an observeOn required for that? Like this:

Observable
    .interval(0, 1, TimeUnit.SECONDS, computationScheduler)
    .observeOn(computationScheduler)
    .flatMap { ... }

Would that observeOn be necessary if I want the emits to be processed on the computation thread?


回答1:


This is simple to verify: just print the current thread to see on which thread the operator is executed:

Observable.just(1, 2, 3, 4, 5, 6, 7, 8, 9)
    .flatMap(e -> {
        System.out.println("on flatmap: " + Thread.currentThread().getName());
        return Observable.just(e).map(x -> "--> " + x);
    })
    .subscribe(s -> {
        System.out.println("on subscribe: " + Thread.currentThread().getName());
        System.out.println(s);
    });

This will always print :

on subscribe: main
--> 1
on flatmap: main
on subscribe: main
--> 2
on flatmap: main
on subscribe: main
--> 3
on flatmap: main
on subscribe: main
--> 4
on flatmap: main
on subscribe: main
--> 5
on flatmap: main
on subscribe: main
--> 6
on flatmap: main
on subscribe: main
--> 7
on flatmap: main
on subscribe: main
--> 8
on flatmap: main
on subscribe: main
--> 9

Processed sequentially because all happen in a single thread -> main.

observeOn will change the downstream execution thread :

Observable.just(1, 2, 3, 4, 5, 6, 7, 8, 9)
    .observeOn(Schedulers.computation())
    .flatMap(e -> {
         System.out.println("on flatmap: " + Thread.currentThread().getName());
         return Observable.just(e).map(x -> "--> " + x);
     })
     .observeOn(Schedulers.io())
     .subscribe(s -> {
         System.out.println("on subscribe: " + Thread.currentThread().getName());
         System.out.println(s);
      });

The result this time will be different for each execution but flatmap and subscribe will be processed in diffrent threads:

on flatmap: RxComputationThreadPool-1
on subscribe: RxCachedThreadScheduler-1

interval will act as observeOn and change the downstream execution thread (scheduler):

Observable.interval(0, 1, TimeUnit.SECONDS, Schedulers.computation())
    .flatMap(e -> {
        System.out.println("on flatmap: " + Thread.currentThread().getName());
        return Observable.just(e).map(x -> "--> " + x);
    })
    .subscribe(s -> {
        System.out.println("on subscribe: " + Thread.currentThread().getName());
        System.out.println(s);
    });

This time the execution is sequential inside one thread of computation scheduler:

on flatmap: RxComputationThreadPool-1
on subscribe: RxComputationThreadPool-1
--> 0
on flatmap: RxComputationThreadPool-1
on subscribe: RxComputationThreadPool-1
--> 1
on flatmap: RxComputationThreadPool-1
on subscribe: RxComputationThreadPool-1
--> 2
on flatmap: RxComputationThreadPool-1
on subscribe: RxComputationThreadPool-1
--> 3
...

interval will by default use the computation scheduler, you don't need to pass it as an argument and observeOn is not needed



来源:https://stackoverflow.com/questions/63560636/rxjava2-interval-and-schedulers

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!