第1章 使用RxJava实现反应式编程 1
1.1 反应式编程与RxJava 1
1.2 何时需要反应式编程 2
1.3 RxJava是如何运行的 3
1.3.1 推送与拉取 3
1.3.2 异步与同步 4
1.3.3 并发与并行 7
1.3.4 延迟执行与立即执行 9
1.3.5 双重性 10
1.3.6 基数 11
1.4 阻塞I/O与非阻塞I/O 15
1.5 反应式抽象 20
第2章 Reactive Extensions 21
2.1 剖析rx.Observable 21
2.2 订阅来自Observable的通知 24
2.3 使用Subscription和Subscriber<T>控制监听器 25
2.4 创建Observable 26
2.4.1 掌握Observable.create() 27
2.4.2 无穷流 30
2.4.3 计时:timer()和interval() 34
2.4.4 hot和cold类型的Observable 34
2.5 用例:从回调API到Observable流 35
2.6 rx.subjects.Subject 40
2.7 ConnectableObservable 42
2.7.1 使用publish().refCount()实现单次订阅 43
2.7.2 ConnectableObservable的生命周期 44
2.8 小结 47
第3章 操作符与转换 48
3.1 核心的操作符:映射和过滤 48
3.1.1 使用map()进行一对一转换 50
3.1.2 使用flatMap()进行包装 53
3.1.3 使用delay()操作符延迟事件 57
3.1.4 flatMap()之后的事件顺序 58
3.1.5 使用concatMap()保证顺序 60
3.2 多个Observable 61
3.2.1 使用merge()将多个Observable合并为一个 62
3.2.2 使用zip()和zipWith()进行成对地组合 63
3.2.3 流之间不同步的情况:combineLatest()、withLatestFrom()和amb() 66
3.3 高级操作符:collect()、reduce()、scan()、distinct()和groupBy() 71
3.3.1 使用Scan和Reduce扫描整个序列 71
3.3.2 使用可变的累加器进行缩减:Collect() 73
3.3.3 使用single()断言的Observable只有一个条目 74
3.3.4 使用distinct()和distinctUntilChanged()丢弃重复条目 74
3.4 使用skip()、takeWhile()等进行切片和切块 76
3.4.1 组合流的方式:concat()、merge()和switchOnNext() 78
3.4.2 使用groupBy()实现基于标准的切块流 84
3.4.3 下一步要学习什么 86
3.5 编写自定义的操作符 87
3.5.1 借助compose()重用操作符 87
3.5.2 使用lift()实现高级操作符 89
3.6 小结 93
第4章 将反应式编程应用于已有应用程序 94
4.1 从集合到Observable 94
4.2 BlockingObservable:脱离反应式的世界 95
4.3 拥抱延迟执行 97
4.4 组合Observable 98
4.5 命令式并发 101
4.6 flatMap()作为异步链接操作符 105
4.7 使用Stream代替回调 109
4.8 定期轮询以获取变更 111
4.9 RxJava的多线程 113
4.9.1 调度器是什么 113
4.9.2 使用subscribeOn()进行声明式订阅 121
4.9.3 subscribeOn()的并发性和行为 124
4.9.4 使用groupBy()进行批量请求 128
4.9.5 使用observeOn()声明并发 129
4.9.6 调度器的其他用途 132
4.10 小结 133
第5章 实现完整的反应式应用程序 134
5.1 解决C10k问题 134
5.1.1 传统的基于线程的HTTP服务器 135
5.1.2 借助Netty和RxNetty实现非阻塞的HTTP服务器 137
5.1.3 阻塞式和反应式服务器的基准测试 144
5.1.4 反应式HTTP服务器之旅 149
5.2 HTTP客户端代码 149
5.3 关系数据库访问 152
5.4 CompletableFuture与Stream 156
5.4.1 CompletableFuture概述 157
5.4.2 与CompletableFuture进行交互 161
5.5 Observable与Single 164
5.5.1 创建和消费Single 165
5.5.2 使用zip、merge和concat组合响应 167
5.5.3 与Observable和CompletableFuture的交互 169
5.5.4 何时使用Single 170
5.6 小结 170
第6章 流控制和回压 171
6.1 流控制 171
6.1.1 定期采样和节流 171
6.1.2 将事件缓冲至列表中 174
6.1.3 窗口移动 179
6.1.4 借助debounce()跳过陈旧的事件 180
6.2 回压 183
6.2.1 RxJava中的回压 184
6.2.2 内置的回压 187
6.2.3 Producer与缺失回压场景 189
6.2.4 按照请求返回指定数量的数据 192
6.3 小结 196
第7章 测试和排错 197
7.1 错误处理 197
7.1.1 我的异常在哪里 198
7.1.2 替代声明式的try-catch 200
7.1.3 事件没有发生导致的超时 203
7.1.4 失败之后的重试 206
7.2 测试和调试 209
7.2.1 虚拟时间 209
7.2.2 单元测试中的调度器 211
7.3 单元测试 213
7.4 监控和调试 219
7.4.1 doOn...()回调 220
7.4.2 测量和监控 221
7.5 小结 223
第8章 案例学习 224
8.1 使用RxJava进行Android开发 224
8.1.1 避免Activity中的内存泄漏 224
8.1.2 Retrofit对RxJava的原生支持 227
8.1.3 Android中的调度器 231
8.1.4 将UI事件作为流 233
8.2 使用Hystrix管理失败 236
8.2.1 使用Hystrix的第一步 236
8.2.2 使用HystrixObservableCommand的非阻塞命令 238
8.2.3 舱壁模式和快速失败 239
8.2.4 批处理和合并命令 241
8.2.5 监控和仪表盘 245
8.3 查询NoSQL数据库 248
8.3.1 Couchbase客户端API 248
8.3.2 MongoDB客户端API 249
8.4 Camel集成 251
8.4.1 通过Camel来消费文件 251
8.4.2 接收来自Kafka的消息 252
8.5 Java 8的Stream和CompletableFuture 252
8.5.1 并行流的用途 253
8.5.2 选择恰当的并发抽象 255
8.5.3 何时使用Observable 255
8.6 内存耗费和泄漏 256
8.7 小结 260
第9章 未来的方向 261
9.1 反应式流 261
9.2 Observable和Flowable 261
9.3 性能 262
9.4 迁移 262
附录A HTTP服务器的更多样例 263
附录B Observable操作符的决策树 269
附录C RxJava 1.0至RxJava 2.0的迁移指南 272
关于作者 306
关于封面 306