在RxJava中有5 different schedulers可供选择:
immediate():创建并返回一个在当前线程上立即执行工作的调度程序。
trampoline():创建并返回一个调度程序,该调度程序对当前工作完成后要执行的当前线程进行排队。
newThread():创建并返回一个Scheduler,为每个工作单元创建一个新线程。
computation():创建并返回用于计算工作的调度程序。这可以用于事件循环,处理回调和其他计算工作。不要在此调度程序上执行IO绑定的工作。使用调度程序。 io()代替。
- 醇>
io():创建并返回一个用于IO绑定工作的调度程序。 该实现由Executor线程池支持,该线程池将根据需要增长。这可用于异步执行阻塞IO。不要在此调度程序上执行计算工作。使用调度程序。计算()代替。
前3个调度程序非常自我解释;但是,我对计算和 io 感到有点困惑。
java.io
)和文件(java.nio.files
)吗?它用于数据库查询吗?它是用于下载文件还是访问REST API?答案 0 :(得分:309)
很棒的问题,我认为文档可以提供更多细节。
io()
由一个无限制的线程池支持,是你用于非计算密集型任务的东西,也就是那些不会给CPU带来太多负担的东西。因此,与文件系统的交互,与不同主机上的数据库或服务的交互就是很好的例子。 computation()
由有限的线程池支持,其大小等于可用处理器的数量。如果你试图在可用处理器之外并行安排cpu密集型工作(比如使用newThread()
),那么当线程争夺处理器并且它可能是潜在的时候,你就会面临线程创建开销和上下文切换开销表现很好。computation()
进行CPU密集型工作,否则您将无法获得良好的CPU利用率。io()
用于计算工作是不好的。io()
是无限制的,如果您在io()
上并行安排了一千个计算任务,那么这千个任务中的每一个都将拥有自己的线程并争夺CPU产生的上下文切换成本。答案 1 :(得分:2)
最重要的一点是,与问题中提到的其他线程池相比, Schedulers.io 和 Schedulers.computation 都是不受限制的线程池支持。如果 Executor 是用 newCachedThreadPool 创建的(无自动回收限制),则 Schedulers.from(Executor)共享此特征。线程池)。
如先前的答复和网络上的多篇文章所充分解释的, Schedulers.io 和 Schedulers.computation 应该谨慎使用,因为它们针对工作类型进行了优化以他们的名字。但是,以我的观点,它们最重要的作用是为响应流提供真正的并发性。
与新人的看法相反,反应流不是固有并发的,而是固有异步和顺序的。因此,只有在I / O操作被阻塞时才使用 Schedulers.io (例如:使用阻塞命令,例如Apache IOUtils FileUtils.readFileAsString(...)< / em>)将冻结调用线程,直到操作完成。
在操作过程中使用Java AsynchronousFileChannel(...)之类的异步方法不会阻塞调用线程,因此没有必要使用单独的线程。实际上, Schedulers.io 线程确实不适合异步操作,因为它们不运行事件循环,并且永远不会调用回调。
相同的逻辑适用于数据库访问或远程API调用。如果可以使用异步或反应性API进行调用,请不要使用 Schedulers.io 。
返回并发。您可能无权访问异步或反应式API来异步或同时执行I / O操作,因此,唯一的选择是在一个单独的线程上分派多个调用。 las,反应流在它们的末端是连续的,但是好消息是 flatMap()运算符可以在其核心引入并发。 >
必须在流结构中构建并发,通常使用 flatMap()运算符。可以配置此功能强大的运算符,以便为您的 flatMap()嵌入式函数
有关RxJava2 Schedulers和Concurrency的文章中找到更多详细信息,您将在其中找到代码示例以及有关如何依次和同时使用Scheduler的详细说明。
希望这会有所帮助,
Softjake
答案 2 :(得分:1)
This blog post provides an excellent answer
摘自博客文章:
Schedulers.io()由无限制的线程池支持。它用于非CPU密集型I / O类型的工作,包括与文件系统的交互,执行网络调用,数据库交互等。该线程池旨在用于异步执行阻塞IO。
Schedulers.computation()由有限制的线程池支持,该线程池的大小取决于可用处理器的数量。它用于计算或CPU密集型工作,例如调整图像大小,处理大型数据集等。请注意:当分配的计算线程多于可用内核时,性能会因上下文切换和线程创建开销而降低,因为线程争夺处理者的时间。
Schedulers.newThread()为计划的每个工作单元创建一个新线程。该调度程序非常昂贵,因为每次都会产生新线程并且不会发生重用。
Schedulers.from(执行程序执行程序)创建并返回由指定执行程序支持的自定义计划程序。若要限制线程池中的并发线程数,请使用Scheduler.from(Executors.newFixedThreadPool(n))。这样可以保证,如果在所有线程都被占用时安排了任务,则该任务将排队。池中的线程将一直存在,直到被明确关闭为止。
RpAndroid扩展库向RxJava提供了主线程或 AndroidSchedulers.mainThread()。主线程(也称为UI线程)是发生用户交互的地方。应该注意不要使该线程过载,以防止不稳定的无响应UI,或者更糟糕的是,“应用程序无响应”(ANR)对话框。
Schedulers.single()是RxJava 2中的新增功能。该调度程序由单个线程支持,该线程按请求的顺序依次执行任务。
Schedulers.trampoline()通过参与的工作线程之一以FIFO(先进先出)的方式执行任务。通常在实现递归时使用,以避免增长调用堆栈。