章节摘要:本章是响应式运行时的「内核视角」——数据流抽象、时间调度、背压呼吸。先建立 Publisher/Subscriber 契约直觉,再谈 Scheduler 三重时间,最后落到
request(n)如何防止内存与线程失控。
| 节 | 焦点 | 关键 API/概念 |
|---|---|---|
| 2.1 | 数据流抽象模型 | Mono/Flux、信号三元组 |
| 2.2 | 时间维度与调度 | Scheduler、VirtualTime |
| 2.3 | 背压机制 | request、buffer/drop/latest |
SOURCE 第二章强调数据流、时间、背压构成不可分割的三角:
onSubscribe → request → onNext → onComplete 时序subscribeOn 与 publishOn 对线程的影响Flux 对慢消费者是危险的这一章的三节不是并列的三块知识,而是同一个运行时问题的三个切面。数据流抽象(2.1)回答「流里装什么、信号怎么传」;时间与调度(2.2)回答「谁在什么线程、何时执行」;背压(2.3)回答「生产快于消费时怎么办」。把它们串起来读:
subscribeOn/publishOn(2.2)本质是「信号的执行线程」;request(n) 后,你再回头看 2.1 的 Mono/Flux,会理解为什么类型本身就承载着「可能 0 个还是 N 个元素」的契约。因此建议一次读完三节而不是分开隔几天读——它们是一个完整的思维拼图。
// 预告:三节知识在同一段代码里相遇 // 2.1 的类型 + 2.2 的调度 + 2.3 的背压 Flux.range(1, 1_000_000) // 2.1 数据流 .subscribeOn(Schedulers.boundedElastic()) // 2.2 源侧线程 .publishOn(Schedulers.parallel()) // 2.2 后续线程 .onBackpressureBuffer(1024) // 2.3 溢出策略 .limitRate(256) // 2.3 主动限速 .subscribe(new SlowConsumer()); // 慢消费者触发背压
本章讲机制;第 3 章讲 Reactive Streams 规范文本如何把机制写成跨库契约。读本章时如果遇到「规范要求……」的表述,先别急着记条文——理解机制后再回到第 3 章对照条文,记忆会牢固得多。
读完本章后,用下面三个问题自测:
onSubscribe → request(2) → onNext(a) → onNext(b) → request(1) → onNext(c) → onComplete 完整画出来,并说明每一步是谁发起的、携带什么参数、处于什么状态?Flux.range(1, 100).map(...).subscribe(),加 subscribeOn(boundedElastic) 与加 publishOn(parallel) 分别影响哪一段?两行代码的差别会导致完全不同的执行线程分布。Flux.interval(1ms) 配上极慢的消费者,不加任何溢出策略会怎样?加 onBackpressureBuffer(100) 会怎样?加 onBackpressureDrop() 又会怎样?三个问题分别对应三节的核心:信号模型、调度器、背压。能答上来,就说明你建立起了「流是带时序的行为」这一心智模型——这正是第 3 章规范文本的阅读前提。
读完本章,你已经具备读懂 Reactive Streams 四接口的能力——下一章进入契约的正式条文。