bigywater.tech
Java · 289

Flow API:Java 中的背压接口

Flow API 只有四个接口,背压全靠 request(n) 这一个方法。这篇手写发布者与处理器,把「谁在哪个线程、什么时候发数据」打印出来。

4 个
Flow 里的接口数,没有任何实现类
256
Flow.defaultBufferSize() 的返回值
2 个
下游只 request(2) 时订阅者实际收到的元素数(共提交 4 个)

Flow 的接口

实测 · 本机执行输出
    Flow 的成员类型:[Processor(接口), Publisher(接口), Subscriber(接口), Subscription(接口)]
    Flow 本身的方法个数:1;defaultBufferSize()=256
      Processor:[] extends [Subscriber, Publisher]
      Subscription:[cancel[], request[long]]
      Subscriber:[onComplete[], onError[Throwable], onNext[Object], onSubscribe[Subscription]]
      Publisher:[subscribe[Subscriber]]

手写发布者

实测 · 本机执行输出
    场景 1:订阅者每次只 request(1),处理完一个再要下一个
      [main     ] onSubscribe
      [main     ] 收到 request(1)
      [pub      ] onNext(1)
      [pub      ] 收到 request(1)
      [pub      ] onNext(2)
      [pub      ] 收到 request(1)
      [pub      ] onNext(3)
      [pub      ] 收到 request(1)
      [pub      ] onNext(4)
      [pub      ] 收到 request(1)
      [pub      ] onNext(5)
      [pub      ] 收到 request(1)
      [pub      ] onComplete
    场景 2:request(3) 一次,之后不再要
      [main     ] onSubscribe
      [main     ] 收到 request(3)
      [pub      ] onNext(1)
      [pub      ] onNext(2)
      [pub      ] onNext(3)
      [main2    ] 300 ms 后仍没有 onComplete,取消
      [main2    ] 收到 cancel()
    场景 3:request(0)
      [main     ] onSubscribe
      [main     ] 收到 request(0)
      [main     ] onError java.lang.IllegalArgumentException: non-positive request
    场景 4:request(Long.MAX_VALUE)(无界)
      [main     ] 收到 request(9223372036854775807)
      [pub      ] onNext(1)
      [pub      ] onNext(2)
      [pub      ] onNext(3)
      [pub      ] onNext(4)
      [pub      ] onNext(5)
      [pub      ] onComplete

手写处理器

实测 · 本机执行输出
      处理器收到上游 onSubscribe
      订阅者 onSubscribe,request(2)
      处理器收到下游 request(2) → 转给上游
      订阅者 onNext <10>
      订阅者 onNext <20>
      只 request 了 2,发 4 个,订阅者看到的见上;现在 close()

分步演示

Flow API
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / OpenJDK(Temurin 17.0.20、Homebrew 21.0.12 与 27,每篇注明实际用的版本);用 javac 编译、java 直接运行,需要第三方库时用 Maven 解析依赖;计时用 System.nanoTime,数字每次运行会有小幅抖动。JDK 21.0.12;发布者与处理器都是为本文手写的最小实现,不符合 Reactive Streams 规范里的全部规则
    • 没有验证:与 Reactive Streams TCK 的一致性、onNext 并发调用的约束、request 累加溢出处理、与 RxJava / Reactor 的适配(Flow 到 Publisher 的桥接)、onSubscribe 之外订阅的错误路径
    京ICP备2026067502号-1京公网安备11010502063487号