问题
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