Schedulers.computation和Schedulers.io的实现有什么区别?

What are the differences in the implementation of Schedulers.computation and Schedulers.io?

为什么它们用于不同类型的任务?在处理计算任务和 io 任务时,它们有什么不同?

Schedulers.computation( ) - meant for computational work such as event-loops and callback processing; do not use this scheduler for I/O (use Schedulers.io( ) instead); the number of threads, by default, is equal to the number of processors


Schedulers.io( ) - meant for I/O-bound work such as asynchronous performance of blocking I/O, this scheduler is backed by a thread-pool that will grow as needed; for ordinary computational work, switch to Schedulers.computation( ); Schedulers.io( ) by default is a CachedThreadScheduler, which is something like a new thread scheduler with thread caching

I/O 和计算是非常不同的工作负载。

计算纯粹是 CPU-bound,所以你想限制线程的数量,这样它们就不会争夺 CPU 并饿死自己。如果您有 1000 个线程都试图在 8 个内核上工作,那么您可能会度过一段糟糕的时光。 Schedulers.computation() 以核心数为上限。

I/O 是不同的,因为虽然他们通常需要一个线程来维护上下文,但他们并没有真正使用 CPU - 他们只是在 I/O 完成之前睡觉。在单核机器上进行 1000 I/O 次操作完全没问题,因为它们大部分时间都处于睡眠状态。 Schedulers.io() 没有上限,将根据需要产生尽可能多的线程

最重要的一点是 Schedulers.io 和 Schedulers.computation 都由无限制的自动回收线程池支持。此特性仅在使用 newCachedThreadPool(不受自动回收线程池限制)创建的情况下由 Schedulers.from(Executor) 共享。

默认情况下,

Schedulers.computation 配置的线程数等于可用 CPU 的数量,因此可以尽可能快地执行计算。您可以增加此数字,但这可能会引入线程切换开销并减慢计算速度。

至于 Schedulers.io,您应该仅将其用于阻塞 I/O 操作,因为它们会阻塞调用线程。如果您的 I/O 调用是通过异步或反应式 API 进行的,请不要使用它,因为没有机制可以在 Scheduler.io 上回调.

也就是说,这些调度程序的一个重要作用是为 flatMap() 运算符提供多线程上下文,从而在反应流的核心实现并发。

从类似问题中找到更多详细信息 and articles on RxJava2 Schedulers and Concurrency,您可以在其中找到详细的解释和代码示例。

希望这对您有所帮助,

软杰克