Project Reactor 3.1.5.RELEASE问题:publishOn配置后订阅仍单线程运行
Project Reactor
publishOn 仅单线程执行的原因及修复方案 问题场景
你这段代码的行为确实容易让人产生困惑:
Flux.range(0, 10) .publishOn(Schedulers.parallel()) .subscribe(i -> LOG.info(i));
你原本预期订阅逻辑会在parallel调度器的多个线程上并行执行,但实际所有日志输出都来自parallel-1线程——这其实是对publishOn的作用理解有偏差导致的。
原因分析
publishOn的核心作用是切换下游操作的执行线程,但它不会自动将数据流拆分为并行流。Flux.range是一个同步的、按顺序逐个发射元素的数据源,publishOn只是把整个序列的处理工作转移到了parallel线程池中的某一个线程上,整个序列依然保持单线程串行执行的状态,自然不会用到多个线程。
简单总结:publishOn只负责线程上下文的切换,不负责并行化拆分数据流——你得先让数据流变成并行结构,它才会调度多线程来处理。
解决方法
要实现多线程并行处理,你需要显式将数据流并行化,推荐使用parallel() + runOn()的组合:
方案1:用parallel()拆分并行轨道
Flux.range(0, 10) .parallel() // 将数据流拆分为多个并行轨道(默认数量等于CPU核心数) .runOn(Schedulers.parallel()) // 指定每个并行轨道使用的线程池 .subscribe(i -> LOG.info(i));
修改后,你就能在日志里看到parallel-1、parallel-2等多个线程的输出了,每个轨道的元素会在独立的线程上处理。如果想自定义并行轨道的数量,可以给parallel()传入参数,比如parallel(4)就固定拆成4个轨道。
额外注意
别混淆publishOn和subscribeOn:subscribeOn是指定上游数据源的发射线程,同样不会自动并行化,只是切换线程上下文而已。
内容的提问来源于stack exchange,提问作者Mikhail Kadan
相关产品推荐
相关产品推荐

