简体   繁体   English

rxjava2 - 在线程池上执行任务的简单示例,在单个线程上进行订阅

[英]rxjava2 - simple example of executing tasks on a thread pool, subscribing on a single thread

I'm experimenting with the following task to get my head around RxJava: 我正在尝试以下任务来了解RxJava:

  • Given a list of URLs 给出一个URL列表
  • Do a HTTP request for each URL on a thread pool 对线程池上的每个URL执行HTTP请求
  • For each result insert some data into an SQLite database (no multithreading here) 对于每个结果,将一些数据插入到SQLite数据库中(此处不进行多线程处理)
  • Block the method until it completes 阻止方法直到完成

So I tried it out in Kotlin: 所以我在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 }

I expected it to print 我希望它能打印出来

pool-1-thread-1 main
pool-1-thread-2 main
pool-1-thread-3 main
pool-1-thread-4 main
....

However it prints: 然而它打印:

pool-1-thread-1 pool-1-thread-1
pool-1-thread-1 pool-1-thread-1
pool-1-thread-1 pool-1-thread-1

Can anyone correct my misunderstandings about how this works? 任何人都可以纠正我对这是如何工作的误解吗? Why does it not use all of the threads of the thread pool? 为什么它不使用线程池的所有线程? How can I get my subscriber to run on the main thread or block until completion? 如何让我的订阅者在主线程或块上运行直到完成?

Rx is not meant as a parallel execution service, use Java's streams api for that. Rx不是一个并行执行服务,使用Java的流api。 Rx events are synchronous, and will flow through the stream subsequently. Rx事件是同步的,并且随后将流过流。 When building the stream, observeOn will request a thread once and process the emissions one by one on that thread. 在构建流时,observeOn将请求一次线程并在该线程上逐个处理排放。

You also expected subscribe to be executed on the main thread. 您还希望subscribe在主线程上执行。 observeOn switches the threads and all downstream events happen on that thread. observeOn切换线程,并在该线程上发生所有下游事件。 If you want to switch to the main thread, you will have to insert another observeOn just before subscribe . 如果要切换到主线程,则必须在subscribe之前插入另一个observeOn

To make code inside your map block work in parallel you should wrap it to observable with own scheduler: 为了使您的内部代码map并行块的工作,你应该把它换到可观察到的与自己的调度:

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) }

In this case, you will see the result: 在这种情况下,您将看到结果:

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
...

You can check article RxJava - Achieving Parallelization that gives explanations of this behavior. 您可以查看文章RxJava - 实现并行化 ,以解释此行为。

Also, RxJava 2.0.5 introduced ParallelFlowable API 此外,RxJava 2.0.5引入了ParallelFlowable API

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM