RxJava疑问:timer、delay等操作符为何默认使用computation调度器?
RxJava:延迟类操作符默认使用computation调度器的原因及常见疑问
1. 延迟属于CPU密集型任务吗?若computation调度器限制为10线程,能否同时运行100个定时器?
- 延迟操作完全不属于CPU密集型任务。这类操作的核心是等待指定时间到期后触发回调,等待过程中几乎不占用CPU资源,底层依赖系统的定时唤醒机制,线程并不会被阻塞在等待逻辑上。
- 即使computation调度器限制为10线程,也完全可以同时运行100个定时器。因为computation调度器基于
ScheduledThreadPoolExecutor实现,定时器的等待由系统调度器管理,线程池中的线程仅在定时器到期后才会被分配执行回调任务。回调执行完成后,线程会回到池中复用,10个线程足以应对大量定时器的回调触发需求——毕竟回调通常都是轻量逻辑,执行速度很快。
2. 在这些操作符中使用IO调度器是否存在问题?
- 从功能层面来说,使用IO调度器不会导致功能异常,IO调度器可以正常处理延迟操作的定时和回调执行。
- 但从性能和资源利用角度看,存在不必要的浪费:
- IO调度器的线程池默认支持动态扩容(最大线程数很大),而延迟操作的回调大多是轻量任务,用computation调度器的固定大小线程池(核心数等于CPU核心数)就足够高效处理,没必要创建额外线程。
- 过多的线程会带来额外的上下文切换开销,反而降低整体性能。
- 例外场景:如果延迟操作的回调本身是IO密集型任务(比如延迟后要执行数据库查询、网络请求),此时指定IO调度器是合理的,可以避免占用computation线程池的资源,让CPU密集型任务优先使用computation线程。
内容的提问来源于stack exchange,提问作者Buckstabue
相关产品推荐
相关产品推荐

