第2章 · 流与信号


第 2 章 · 流与信号

章节摘要:本章是响应式运行时的「内核视角」——数据流抽象、时间调度、背压呼吸。先建立 Publisher/Subscriber 契约直觉,再谈 Scheduler 三重时间,最后落到 request(n) 如何防止内存与线程失控。

本章结构

节 焦点 关键 API/概念
2.1 数据流抽象模型 Mono/Flux、信号三元组
2.2 时间维度与调度 Scheduler、VirtualTime
2.3 背压机制 request、buffer/drop/latest

三维骨架

SOURCE 第二章强调数据流、时间、背压构成不可分割的三角:

  • 没有流抽象,谈不上组合
  • 没有时间语义,异步不可推理
  • 没有背压,高吞吐必溢出

读完本章应能

  1. 画出 onSubscribe → request → onNext → onComplete 时序
  2. 说明 subscribeOn 与 publishOn 对线程的影响
  3. 解释为何无界 Flux 对慢消费者是危险的

三者的关系

这一章的三节不是并列的三块知识,而是同一个运行时问题的三个切面。数据流抽象(2.1)回答「流里装什么、信号怎么传」;时间与调度(2.2)回答「谁在什么线程、何时执行」;背压(2.3)回答「生产快于消费时怎么办」。把它们串起来读:

  • 2.1 建立信号模型后,你会发现 subscribeOn/publishOn(2.2)本质是「信号的执行线程」;
  • 2.2 引入调度器后,你会发现背压信号(2.3)必须跨线程传播才有意义;
  • 2.3 讲完 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 章衔接

本章讲机制;第 3 章讲 Reactive Streams 规范文本如何把机制写成跨库契约。读本章时如果遇到「规范要求……」的表述,先别急着记条文——理解机制后再回到第 3 章对照条文,记忆会牢固得多。

本章的验收标准

读完本章后,用下面三个问题自测:

  1. 能画出信号时序吗:给出一张纸,把 onSubscribe → request(2) → onNext(a) → onNext(b) → request(1) → onNext(c) → onComplete 完整画出来,并说明每一步是谁发起的、携带什么参数、处于什么状态?
  2. 能解释调度差异吗:同样的 Flux.range(1, 100).map(...).subscribe(),加 subscribeOn(boundedElastic) 与加 publishOn(parallel) 分别影响哪一段?两行代码的差别会导致完全不同的执行线程分布。
  3. 能预测溢出行为吗:一个 Flux.interval(1ms) 配上极慢的消费者,不加任何溢出策略会怎样?加 onBackpressureBuffer(100) 会怎样?加 onBackpressureDrop() 又会怎样?

三个问题分别对应三节的核心:信号模型、调度器、背压。能答上来,就说明你建立起了「流是带时序的行为」这一心智模型——这正是第 3 章规范文本的阅读前提。

章节知识地图

读完本章,你已经具备读懂 Reactive Streams 四接口的能力——下一章进入契约的正式条文。

作者与出处
原作者:灏天文库
来源:平台策划编纂
整理人: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U