我面对非常奇怪的RxJava行为,我无法理解。
我想要并行处理元素。我正在使用flatMap:
public static void log(String msg) {
String threadName = Thread.currentThread().getName();
System.out.println(String.format("%s - %s", threadName, msg));
}
public static void sleep(int ms) {
try {
Thread.sleep(ms);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws InterruptedException {
Scheduler sA = Schedulers.from(Executors.newFixedThreadPool(1));
Scheduler sB = Schedulers.from(Executors.newFixedThreadPool(5));
Observable.create(s -> {
while (true) {
log("start");
s.onNext(Math.random());
sleep(10);
}
}).subscribeOn(sA)
.flatMap(r -> Observable.just(r).subscribeOn(sB))
.doOnNext(r -> log("process"))
.subscribe((r) -> log("finish"));
}
输出非常可预测:
pool-1-thread-1 - start
pool-2-thread-1 - process
pool-2-thread-1 - finish
pool-1-thread-1 - start
pool-2-thread-2 - process
pool-2-thread-2 - finish
pool-1-thread-1 - start
pool-2-thread-3 - process
pool-2-thread-3 - finish
好吧,但如果我用n>添加睡眠10,flatMap并行化调度程序停止更改线程后的映射。
public static void main(String[] args) throws InterruptedException {
Scheduler sA = Schedulers.from(Executors.newFixedThreadPool(1));
Scheduler sB = Schedulers.from(Executors.newFixedThreadPool(5));
Observable.create(s -> {
while (true) {
log("start");
s.onNext(Math.random());
sleep(10);
}
}).subscribeOn(sA)
.flatMap(r -> Observable.just(r).subscribeOn(sB))
.doOnNext(r -> sleep(15))
.doOnNext(r -> log("process"))
.subscribe((r) -> log("finish"));
}
什么给出了以下内容:
pool-1-thread-1 - start
pool-1-thread-1 - start
pool-2-thread-1 - process
pool-2-thread-1 - finish
pool-1-thread-1 - start
pool-1-thread-1 - start
pool-2-thread-1 - process
pool-2-thread-1 - finish
pool-1-thread-1 - start
pool-2-thread-1 - process
WHY ???为什么在flatMap之后在同一个线程(pool-2-thread-1)中处理所有元素?
答案 0 :(得分:2)
FlatMap将任何并行任务序列化为单个线程,您正在窥视这个线程。试试这个
public static void main(String[] args) throws InterruptedException {
Scheduler sA = Schedulers.from(Executors.newFixedThreadPool(1));
Scheduler sB = Schedulers.from(Executors.newFixedThreadPool(5));
Observable.create(s -> {
while (!s.isUnsubscribed()) {
log("start");
s.onNext(Math.random());
sleep(10);
}
}).subscribeOn(sA)
.flatMap(r ->
Observable.just(r)
.subscribeOn(sB)
.doOnNext(r -> sleep(15))
.doOnNext(r -> log("process"))
)
.subscribe((r) -> log("finish"));
}