本书是一本关于并发编程技术的教程,书中详细介绍了并发编程中的主要概念和基本数据结构,包括传统并发模型、基于Future 和Promise的异步编程、数据并行容器、基于响应式扩展的并发编程、软件事务性内存、角色模型、并发编程实践和反应器编程模型等。本书基于Scala语言编写,实例丰富,可操作性很强。
本书面向的用户群体以Scala用户为主,因为书中所有的示例都是基于Scala代码的。但其他语言用户也可以从中获益良多,因为书中介绍的并发编程概念是普遍适用的,并不局限于特定编程语言,只不过Scala比较适用于并发编程而已。
1.本书由Scala发明人亲传弟子执笔完成,颇具权威性。
2.通过大量的实际案例,兼顾理论与实践,带领读者熟悉并发领域的尖端技术。
3.提供代码下载,且代码可重用。
Scala是一种现代的多范式编程语言,旨在以简洁、优雅和安全的方式表达常见的编程模式。Scala流畅地集成了面向对象语言和函数式语言的特性。
在本书中,您会看到Scala 2.12平台的更新内容(Scala 2.12系列针对Java 8执行程序)。本书首先向您介绍JVM并发编程的基础,概述了Java内存模型的基本知识,然后展示了一些经典的构建块的并发性,如原子性变量、线程池和并发数据结构,以及对传统并发性的说明。
接着,本书介绍了不同的高级并发抽象,每种抽象都针对特定的编程任务类,同时还介绍了Scala异步编程功能的演进,涵盖了一些与所描述的技术配套使用的有效模式和习惯用法。最后,本书概述了何时使用哪个并发库,并演示了它们协同工作的方法,同时介绍了构建并发和分布式系统的全新方法。
目标读者
不管是Scala并发编程的初学者,还是具备一定经验的Scala编程人员,通过阅读本书,相信您都会有所收获。当然,具备Scala编程语言的基本知识将对阅读本书很有帮助。
您将从这本书中学到什么:
■ 掌握现代多处理器系统并发编程的基础;
■ 通过简单的低级并发原语构建高性能并发系统;
■ 基于Future和Promise来表现并发计算中的异步性;
■ 通过使用数据并行容器来无缝地加速串行编程;
■ 设计安全、可扩展且易于理解的内存事务数据模型;
■ 创建可在多台计算机上扩展的分布式应用程序;
■ 在大型应用程序中集成不同的并发框架;
■ 在Scala 2.12中开发和实施可扩展且易于理解的并发应用程序。
Aleksandar Prokopec 是一位软件开发者,同时也是并发和分布式编程技术研究者。他拥有克罗地亚萨格勒布大学电子工程和计算学院的计算机专业硕士学位和瑞士洛桑联邦理工大学(EPFL)的计算机科学专业博士学位。作为 EPFL 博士助教和 Scala 语言开发团队成员,他积极为 Scala 编程语言做贡献,研究并发编程抽象、并行数据编程支持和 Scala并发数据结构。他编写了 Scala Parallel Collections 框架,这是一个高级的 Scala 并行数据编程库。他还参加了多个 Scala 并发库开发小组,开发了 Future、Promise 和 ScalaSTM 等抽象。
第 1章 概述 1
1.1 并发编程 2
1.1.1 传统并发计算概述 2
1.1.2 现代并发编程范式 3
1.2 Scala的优势 4
1.3 准备工作 5
1.3.1 执行一个Scala程序 5
1.3.2 初识Scala 6
1.4 小结 10
1.5 练习 11
第 2章 JVM和JMM上的并发性 13
2.1 进程和线程 14
2.1.1 线程的创建和启动 16
2.1.2 原子执行 20
2.1.3 重排序 24
2.2 监控器和同步 26
2.2.1 死锁 28
2.2.2 保护块 30
2.2.3 线程中断和平滑关闭 34
2.3 易失变量 35
2.4 JMM 37
2.5 小结 40
2.6 练习 41
第3章 并发编程的传统构造模块 45
3.1 Executor和ExecutionContext对象 46
3.2 原子性原语 49
3.2.1 原子性变量 49
3.2.2 无锁编程 52
3.2.3 锁的实现 54
3.2.4 ABA问题 56
3.3 懒值 58
3.4 并发容器 62
3.4.1 并发队列 64
3.4.2 并发集合和映射 66
3.4.3 并发遍历 71
3.5 定制的并发数据结构 73
3.5.1 实现一个无锁的并发池 74
3.5.2 进程的创建和处理 78
3.6 小结 79
3.7 练习 80
第4章 基于Future和Promise的异步编程 82
4.1 Future 83
4.1.1 启动Future计算 84
4.1.2 Future回调 86
4.1.3 Future和异常 88
4.1.4 使用Try类型 89
4.1.5 致命异常 90
4.1.6 Future上的函数式组合 91
4.2 Promise 98
4.2.1 包装基于回调的API 100
4.2.2 扩展Future API 102
4.2.3 异步计算的取消 103
4.3 Future和阻塞 106
4.3.1 等待Future完成 106
4.3.2 在异步计算内部阻塞 107
4.4 Scala的Async库 108
4.5 其他Future框架 110
4.6 小结 112
4.7 练习 112
第5章 数据并行容器 116
5.1 Scala容器概述 117
5.2 使用并行容器 117
5.2.1 并行容器的类继承谱系 121
5.2.2 配置并行层次 122
5.2.3 测量JVM上的性能 123
5.3 并行容器的缺点 125
5.3.1 不可并行容器 125
5.3.2 不可并行操作 126
5.3.3 并行操作中的副作用 128
5.3.4 非确定性的并行操作 129
5.3.5 可交换和可结合的操作 131
5.4 将并行容器和并发容器结合起来 132
5.5 实现定制的并行容器 134
5.5.1 分裂器 135
5.5.2 组合器 138
5.6 小结 141
5.7 练习 142
第6章 基于响应式扩展的并发编程 143
6.1 创建Observable对象 144
6.1.1 Observable对象和异常 146
6.1.2 Observable规约 147
6.1.3 定制Observable对象 149
6.1.4 由Future对象创建Observable对象 150
6.1.5 订阅 151
6.2 Observable对象的组合 154
6.2.1 嵌套Observable对象 155
6.2.2 Observable对象的错误处理 160
6.3 Rx调度器 163
6.4 Subject和自顶向下响应式编程 169
6.5 小结 173
6.6 练习 174
第7章 软件事务性内存 176
7.1 原子性变量的问题 177
7.2 使用STM 180
7.2.1 事务性引用 182
7.2.2 使用atomic语句 183
7.3 事务的组合 185
7.3.1 事务间的交互和副作用 185
7.3.2 单操作事务 189
7.3.3 嵌套的事务 190
7.3.4 事务和异常 193
7.4 事务的重试 197
7.5 事务性容器 202
7.5.1 事务局部变量 202
7.5.2 事务性数组 203
7.5.3 事务性映射 205
7.6 小结 206
7.7 练习 207
第8章 角色模型 210
8.1 使用角色模型 211
8.1.1 创建角色系统和角色实例 213
8.1.2 未处理消息的管理 216
8.1.3 角色行为和状态 217
8.1.4 Akka角色的层次关系 221
8.1.5 角色的查找 224
8.1.6 角色的生命周期 226
8.2 角色之间的通信 230
8.2.1 ask模式 231
8.2.2 转发模式 234
8.2.3 角色终止 235
8.3 角色的监管 237
8.4 远程角色 242
8.5 小结 246
8.6 练习 246
第9章 并发编程实践 248
9.1 选择并发性编程的正确工具 248
9.2 将所有工具组合起来——编写一个远程文件浏览器 252
9.2.1 文件系统建模 253
9.2.2 服务器接口 256
9.2.3 客户端API 258
9.2.4 客户端程序的用户界面 261
9.2.5 实现客户端逻辑 265
9.2.6 改进远程文件浏览器 270
9.3 调试并发性程序 271
9.3.1 死锁和没有进度 272
9.3.2 程序错误输出的调试 276
9.3.3 性能调优 280
9.4 小结 286
9.5 练习 286
第 10章 反应器编程模型 289
10.1 对反应器的需求 290
10.2 开始使用Reactor 291
10.3 Hello World程序 291
10.4 事件流 293
10.4.1 事件流的生命周期 294
10.4.2 事件流的函数式组合 295
10.5 反应器 297
10.5.1 反应器的定义和配置 299
10.5.2 使用通道 300
10.6 调度器 302
10.7 反应器生命周期 304
10.8 反应器系统服务 305
10.8.1 日志服务 306
10.8.2 时钟服务 306
10.8.3 Channels服务 307
10.8.4 定制服务 309
10.9 协议 310
10.9.1 定制一个服务器—客户端协议 311
10.9.2 标准服务器—客户端协议 313
10.9.3 路由协议 316
10.9.4 两路协议 318
10.10 小结 321
10.11 练习 321