Flow.Publisher 是 Reactive Streams 规范的 1:1 接口映射,非 Java 自研实现;它仅承诺“能发数据”,无背压自动处理、无操作符链、无线程调度,需手动调用 onSubscribe() 和 request() 启动流。

Flow.Publisher 是什么,不是什么
它不是 Java 自己发明的响应式流实现,而是对 Reactive Streams 规范的 1:1 接口映射。Java 9 把 Publisher、Subscriber、Subscription、Processor 这四个接口直接搬进 java.util.concurrent.Flow,不带任何默认行为,也不依赖第三方库。
常见错误是把它当 Flux 或 Observable 用——它没有背压自动处理、没有线程调度、没有操作符链。你写一个类实现 Publisher,就只是承诺“我能发数据”,别的全得自己填。
- 必须手动调用
Subscriber.onSubscribe(),否则下游永远收不到信号 -
Subscription.request(long n)是唯一合法的“拉取”入口,不能在onSubscribe外提前发数据 - 如果
request(1)后没调用onNext(),就违反规范,下游可能卡死或抛IllegalStateException
为什么 Flow.Subscriber 的 onSubscribe() 必须立刻保存 Subscription
因为 Subscription 是背压控制的唯一手柄,且规范明确禁止在 onSubscribe 之外缓存或延迟持有它。很多初学者在 onSubscribe 里只记下 subscription,却忘了马上调用 subscription.request(1),结果整个流静默无输出。
典型场景:自定义限流 Publisher,需要根据下游消费能力动态决定下次 request 数量。这时候如果没在 onSubscribe 里立刻 request,就等于没启动流。
立即学习“Java免费学习笔记(深入)”;
- 不能把
Subscription存成字段后“稍后再用”——规范要求“immediate use” - 不能在
onNext()里才第一次调用request(),这会导致第一个元素永远发不出去 - 如果下游
Subscriber是你自己写的,务必检查onSubscribe是否真的触发了request()
Flow.Processor 为什么几乎没人直接用
它既是 Publisher 又是 Subscriber,理论上能做转换、缓冲、过滤,但 Java 9 没提供任何开箱即用的实现,也没有线程安全保证。你要自己实现,就得同时处理两个方向的并发、背压对齐、取消传播、异常隔离——成本远超收益。
真实使用中,大家要么用 SubmissionPublisher(JDK 自带的线程安全 Publisher),要么直接切到 Project Reactor 或 RxJava。硬啃 Processor 接口,99% 最终会掉进重入、状态竞争、cancel 不同步的坑里。
-
SubmissionPublisher支持ForkJoinPool调度和maxBufferCapacity控制,比手写Processor稳定得多 - 如果你真需要中间处理,优先考虑
SubmissionPublisher+ 自定义Subscriber组合,而非实现Processor - JDK 从未承诺
Flow.Processor的线程模型,多线程环境下必须自己加锁或用AtomicReferenceFieldUpdater
SubmissionPublisher 的 submit() 和 offer() 区别在哪
submit() 是阻塞式提交:如果缓冲区满,它会等有空间再发;offer() 是非阻塞式,缓冲区满就直接返回 false。选哪个,取决于你能否容忍丢数据或是否愿意挂起当前线程。
性能上,offer() 更轻量,适合高吞吐、可容忍丢失的场景(比如监控打点);submit() 更稳妥,但可能因等待拖慢上游,尤其在单线程发布时容易引发背压雪崩。
-
submit()内部会调用awaitSpace(),可能触发ForkJoinPool的 work-stealing,但也会增加延迟 -
offer()返回false后,你得自己决定是重试、降级还是跳过——JDK 不管这个逻辑 - 两者都遵循背压,但
submit()的“等待”行为容易掩盖下游消费慢的问题,调试时更难定位瓶颈
Subscription.request(),不许在 onSubscribe 外初始化流,不许假设线程安全。这些不是设计缺陷,而是为了和 Reactive Streams 生态对齐。越想省事跳过它们,后面 debug 越像在解谜。










