我正在尝试以下任务来了解RxJava:
所以我在Kotlin试了一下:
val ex = Executors.newFixedThreadPool(10)
Observable.fromIterable((1..100).toList())
.observeOn(Schedulers.from(ex))
.map { Thread.currentThread().name }
.subscribe { println(it + " " + Thread.currentThread().name }
我希望它能打印
pool-1-thread-1 main
pool-1-thread-2 main
pool-1-thread-3 main
pool-1-thread-4 main
....
然而它打印:
pool-1-thread-1 pool-1-thread-1
pool-1-thread-1 pool-1-thread-1
pool-1-thread-1 pool-1-thread-1
任何人都可以纠正我对这是如何工作的误解吗?为什么它不使用线程池的所有线程?如何让我的订阅者在主线程或块上运行直到完成?
答案 0 :(得分:4)
Rx并不是一个并行执行服务,使用Java的流api。 Rx事件是同步的,并且随后将流过流。在构建流时,observeOn将请求一次线程并在该线程上逐个处理排放。
您还希望在主线程上执行subscribe
。 observeOn
切换线程,并在该线程上发生所有下游事件。如果要切换到主线程,则必须在observeOn
之前插入另一个subscribe
。
答案 1 :(得分:1)
要使map
块中的代码并行工作,您应该使用自己的调度程序将其包装到observable中:
val ex = Executors.newFixedThreadPool(10)
val scheduler = Schedulers.from(ex)
Observable.fromIterable((1..100).toList())
.flatMap {
Observable
.fromCallable { Thread.currentThread().name }
.subscribeOn(scheduler)
}
.subscribe { println(it + " " + Thread.currentThread().name) }
在这种情况下,您将看到结果:
pool-1-thread-1 pool-1-thread-1
pool-1-thread-2 pool-1-thread-1
pool-1-thread-3 pool-1-thread-1
pool-1-thread-4 pool-1-thread-1
...
您可以查看解释此行为的文章RxJava - Achieving Parallelization。
此外,RxJava 2.0.5引入了ParallelFlowable API