描述
开 本: 16开纸 张: 胶版纸包 装: 平装-胶订是否套装: 否国际标准书号ISBN: 9787111625063
编辑推荐
选择正确的并发(concurrent)体系结构对应用程序的设计和性能有重大影响,这本书解释了如何利用并行(parallel)体系结构的不同特性,使代码更快、更高效地运行。
本书全面阐述并发设计模式,并展示这些模式背后的基本原理及设计方案。书中首先介绍基本的并发概念,并探索显式锁定、无锁编程、future模式和actor模式;然后深入探讨不同的并发模型和并行算法,并将它们应用到不同的实际场景中,以挖掘应用程序的真正潜力。本书将帮助你完整了解多线程设计模式,如主/从模式、leader/followers模式、map-reduce模式以及监视器模式,还将帮助你使用这些模式进行实际编码。
本书全面阐述并发设计模式,并展示这些模式背后的基本原理及设计方案。书中首先介绍基本的并发概念,并探索显式锁定、无锁编程、future模式和actor模式;然后深入探讨不同的并发模型和并行算法,并将它们应用到不同的实际场景中,以挖掘应用程序的真正潜力。本书将帮助你完整了解多线程设计模式,如主/从模式、leader/followers模式、map-reduce模式以及监视器模式,还将帮助你使用这些模式进行实际编码。
通过阅读本书,你将:
探索并行体系结构。
熟悉并发模型。
通过实现多线程模式来内化设计主题。
深入了解并发设计模式。
发现众多Java线程抽象背后的设计原则。
使用函数式并发模式。
内容简介
本书解释了如何利用并行体系结构的不同特性,使代码更快、更高效。首先介绍基本的并发概念,并探索围绕显式锁定、无锁编程、future模式和actor模式。其次,深入讲解不同的并发模型和并行算法,并将它们应用到不同的场景中,以挖掘应用程序的真正潜力。本书将带读者了解多线程设计模式,如主/从模式,Leader/Followers模式,map-reduce模式,以及监视器模式,还将帮助读者学习使用这些模式的实际编码。
目 录
译者序
前言
作者/评阅者简介
第1章 并发简介1
1.1 并发轻而易举2
1.1.1 推动并发3
1.1.2 分时6
1.1.3 两种并发编程模型7
1.2 消息传递模型8
1.2.1 协调和通信10
1.2.2 流控制12
1.2.3 分治策略14
1.2.4 进程状态的概念15
1.3 共享内存和共享状态模型16
1.3.1 线程交错—同步的需要18
1.3.2 竞争条件和海森堡bug20
1.3.3 正确的内存可见性和happens-before原则21
1.3.4 共享、阻塞和公平22
1.3.5 异步与同步执行24
1.3.6 Java的非阻塞I/O25
1.4 模式和范式26
1.4.1 事件驱动的架构28
1.4.2 响应式编程29
1.4.3 actor范式31
1.4.4 消息代理32
1.4.5 软件事务性内存33
1.4.6 并行集合34
1.5 本章小结35
第2章 并发模式初探37
2.1 线程及其上下文38
2.2 竞争条件40
2.2.1 监视器模式44
2.2.2 线程安全性、正确性和不变性45
2.2.3 双重检查锁定48
2.2.4 显式锁定52
2.2.5 生产者/消费者模式60
2.2.6 比较和交换66
2.3 本章小结68
第3章 更多的线程模式70
3.1 有界缓冲区72
3.1.1 策略模式—客户端轮询74
3.1.2 接管轮询和睡眠的策略75
3.1.3 使用条件变量的策略77
3.2 读写锁78
3.2.1 易读的RW锁80
3.2.2 公平锁84
3.3 计数信号量86
3.4 我们自己的重入锁89
3.5 倒计时锁存器91
3.6 循环屏障95
3.7 future任务97
3.8 本章小结100
第4章 线程池101
4.1 线程池102
4.1.1 命令设计模式104
4.1.2 单词统计105
4.1.3 单词统计的另一个版本107
4.1.4 阻塞队列107
4.1.5 线程中断语义111
4.2 fork-join池111
4.2.1 Egrep—简易版112
4.2.2 为什么要使用递归任务113
4.2.3 任务并行性116
4.2.4 使用fork-join API实现快速排序117
4.2.5 map-reduce技术124
4.3 线程的工作窃取算法125
4.4 主动对象128
4.4.1 隐藏和适应129
4.4.2 使用代理129
4.5 本章小结132
第5章 提升并发性133
5.1 无锁堆栈134
5.1.1 原子引用134
5.1.2 堆栈的实现135
5.2 无锁的FIFO队列137
5.2.1 流程如何运作140
5.2.2 无锁队列141
5.2.3 ABA问题147
5.3 并发的哈希算法152
5.3.1 add(v)方法153
5.3.2 contains(v)方法156
5.4 大锁的方法157
5.5 锁条纹设计模式159
5.6 本章小结162
第6章 函数式并发模式163
6.1 不变性164
6.1.1 不可修改的包装器165
6.1.2 持久数据结构167
6.1.3 递归和不变性169
6.2 future模式170
6.2.1 apply方法171
6.2.2 future—线程映射173
6.2.3 future模式是异步的174
6.2.4 糟糕的阻塞177
6.2.5 函数组合179
6.3 本章小结182
第7章 actor模式183
7.1 消息驱动的并发183
7.1.1 什么是actor185
7.1.2 状态封装189
7.1.3 并行性在哪里190
7.1.4 未处理的消息192
7.1.5 become模式193
7.1.6 让它崩溃并恢复197
7.1.7 actor通信—ask模式199
7.1.8 actor通信—tell模式204
7.1.9 pipeTo模式205
7.2 本章小结207
前言
作者/评阅者简介
第1章 并发简介1
1.1 并发轻而易举2
1.1.1 推动并发3
1.1.2 分时6
1.1.3 两种并发编程模型7
1.2 消息传递模型8
1.2.1 协调和通信10
1.2.2 流控制12
1.2.3 分治策略14
1.2.4 进程状态的概念15
1.3 共享内存和共享状态模型16
1.3.1 线程交错—同步的需要18
1.3.2 竞争条件和海森堡bug20
1.3.3 正确的内存可见性和happens-before原则21
1.3.4 共享、阻塞和公平22
1.3.5 异步与同步执行24
1.3.6 Java的非阻塞I/O25
1.4 模式和范式26
1.4.1 事件驱动的架构28
1.4.2 响应式编程29
1.4.3 actor范式31
1.4.4 消息代理32
1.4.5 软件事务性内存33
1.4.6 并行集合34
1.5 本章小结35
第2章 并发模式初探37
2.1 线程及其上下文38
2.2 竞争条件40
2.2.1 监视器模式44
2.2.2 线程安全性、正确性和不变性45
2.2.3 双重检查锁定48
2.2.4 显式锁定52
2.2.5 生产者/消费者模式60
2.2.6 比较和交换66
2.3 本章小结68
第3章 更多的线程模式70
3.1 有界缓冲区72
3.1.1 策略模式—客户端轮询74
3.1.2 接管轮询和睡眠的策略75
3.1.3 使用条件变量的策略77
3.2 读写锁78
3.2.1 易读的RW锁80
3.2.2 公平锁84
3.3 计数信号量86
3.4 我们自己的重入锁89
3.5 倒计时锁存器91
3.6 循环屏障95
3.7 future任务97
3.8 本章小结100
第4章 线程池101
4.1 线程池102
4.1.1 命令设计模式104
4.1.2 单词统计105
4.1.3 单词统计的另一个版本107
4.1.4 阻塞队列107
4.1.5 线程中断语义111
4.2 fork-join池111
4.2.1 Egrep—简易版112
4.2.2 为什么要使用递归任务113
4.2.3 任务并行性116
4.2.4 使用fork-join API实现快速排序117
4.2.5 map-reduce技术124
4.3 线程的工作窃取算法125
4.4 主动对象128
4.4.1 隐藏和适应129
4.4.2 使用代理129
4.5 本章小结132
第5章 提升并发性133
5.1 无锁堆栈134
5.1.1 原子引用134
5.1.2 堆栈的实现135
5.2 无锁的FIFO队列137
5.2.1 流程如何运作140
5.2.2 无锁队列141
5.2.3 ABA问题147
5.3 并发的哈希算法152
5.3.1 add(v)方法153
5.3.2 contains(v)方法156
5.4 大锁的方法157
5.5 锁条纹设计模式159
5.6 本章小结162
第6章 函数式并发模式163
6.1 不变性164
6.1.1 不可修改的包装器165
6.1.2 持久数据结构167
6.1.3 递归和不变性169
6.2 future模式170
6.2.1 apply方法171
6.2.2 future—线程映射173
6.2.3 future模式是异步的174
6.2.4 糟糕的阻塞177
6.2.5 函数组合179
6.3 本章小结182
第7章 actor模式183
7.1 消息驱动的并发183
7.1.1 什么是actor185
7.1.2 状态封装189
7.1.3 并行性在哪里190
7.1.4 未处理的消息192
7.1.5 become模式193
7.1.6 让它崩溃并恢复197
7.1.7 actor通信—ask模式199
7.1.8 actor通信—tell模式204
7.1.9 pipeTo模式205
7.2 本章小结207
前 言
感谢你购买本书!我们生活在一个并发的世界中,并发编程是一项越来越有价值的技能。
我还记得当我理解了UNIX shell管道的工作原理的那一刻,便立即对Linux和命令行“一见钟情”,并尝试了许多通过管道连接的组合过滤器(过滤器是一种程序,它从标准输入设备读取数据,再写入标准输出设备)。我一直都在和并发程序打交道,我对命令行的创造性和力量感到很惊讶。
后来,由于项目变化,我致力于用多线程范式编写代码。所使用的编程语言是我钟爱的C或C++,然而,令我惊讶的是,我发现维护一个用C/C++编写的多线程遗留代码库是一项艰巨的任务。这是因为共享状态是随意管理的,一个小错误就可能让我们陷入调试噩梦!
大约在那个时候,我开始了解面向对象设计模式和一些多线程模式。例如,我们希望将一个大的内存数据结构安全地显露给多个线程。我读过有关reader/writer锁模式的内容,该模式使用智能指针(一种C++习语),并据此编写解决方案。
采取此方法后并发错误就消失了!此外,该模式使得线程很容易理解。在我们的示例中,writer线程需要对共享数据结构进行不频繁但独占的访问,reader线程只是将这个结构作为不可变的实体来使用。看啊,没有锁!
没锁带来巨大的好处,随着锁的消失,死锁、竞争和饥饿的可能性也随之消失。感觉真棒!
我在这里得到了一个教训!我得不断学习设计模式,根据不同模式努力思考手边的设计问题。这也帮助我更好地理解代码!最终,我对如何驯服并发这头野兽有了初步的了解!
设计模式是用于解决常见设计问题的可重复使用的解决方案。设计解决方案就是设计模式。你的问题领域可能会有所不同,也就是说,你需要编写的业务逻辑将用于解决你手中的业务问题。但是,一旦使用模式,任务就能很快完成!
例如,当我们使用面向对象范式编写代码时,我们使用“四人组”(GoF)开发的设计模式(http://wiki.c2.com/?DesignPatternsBook)。这本名著为我们提供了一系列设计问题及其解决方案。虽然这种策略模式一直保持不变,但它仍被人们广泛使用。
几年后,我转战到Java领域,并使用ExecutorService接口来构建我的代码。开发代码非常容易,几个月的运行中没有出现任何重大问题。(虽然有一些其他问题,但没有数据冲突,也没有烦琐的调试!)
随后,我进入函数式编程的世界,并开始编写越来越多的Scala程序。这是一个以不变数据结构为标准的新领域,我学到了一种截然不同的范式。
Scala的future模式和actor模式给出了全新的视角。作为程序员,我能感受到这些工具带来的力量。一旦你跨越了认知曲线(诚然在开始时有点畏惧),就能编写许多更安全且经得起推敲的并发代码。
本书讲述了许多并发设计模式,展示了这些模式背后的基本原理,突出了设计方案。
本书目标读者
我们假定你有一定的Java编程基础,理想情况下,你已经用过多线程Java程序,并熟悉“四人组”的设计模式,你还能轻松地通过maven运行Java程序。
本书将带你进入下一个阶段,同时向你展示许多并发模式背后的设计主题。本书希望帮助开发人员通过学习模式来构建可扩展、高性能的应用程序。
本书包含的内容
第1章介绍并发编程。正如你将看到的,并发本身就是一个领域。你将了解UNIX进程以及并发模式的管道和过滤器。本章涉及并发编程的综述,你可能已对这方面有所了解。
第2章涵盖一些关键的基本概念,并介绍Java内存模型的本质。你将了解共享状态模型中出现的竞争条件和问题,并尝试第一个并发模式:手拉手锁定。
第3章包括显式同步可变状态和监视器模式,你会看到这种方法存在很多问题。我们将详细介绍主动对象设计模式。
第4章介绍线程如何通过生产者/消费者模式相互通信,并介绍线程通信的概念,然后解释主/从设计模式。本章还将介绍fork-join模式的一个特例:map-reduce模式。
第5章讨论构建块,还将讨论阻塞队列、有界队列、锁存器、FutureTask、信号量、屏障、激活和安全等内容。最后,描述不可变性以及不可变数据结构固有的线程安全性。
第6章介绍future并讨论它的一元性质,包括转型和单子模式,还将阐释future模式的构成,同时会介绍Promise类。
第7章介绍actor范式。再次回顾主动对象模式,然后解释actor范式,特别是未明确的锁定性质。还将讨论ask与tell、become模式(并强调其不变性)、流水线、半同步或半异步,并通过示例代码进行说明。
读者水平及所需环境
为了充分利用本书,你应该掌握一定水平的Java编程知识和Java线程基础知识,能够使用Java构建工具maven。书中提供了需要复习的重要内容,并通过Java线程示例对此进行补充。
使用诸如IntelliJ Idea、Eclipse或Netbeans等集成开发环境会很有帮助,但并非必须。为了说明函数并发模式,最后两章使用Scala,这两章的代码使用基本的Scala结构。我们建议读者最好浏览一下介绍性的Scala教程,这样做很有益处。
下载示例代码及彩色图像
本书的示例代码及所有截图和样图,可以从http://www.packtpub.com通过个人账号下载,也可以访问华章图书官网http://www.hzbook.com,通过注册并登录个人账号下载。另外还可以从https://github.com/PacktPub
我还记得当我理解了UNIX shell管道的工作原理的那一刻,便立即对Linux和命令行“一见钟情”,并尝试了许多通过管道连接的组合过滤器(过滤器是一种程序,它从标准输入设备读取数据,再写入标准输出设备)。我一直都在和并发程序打交道,我对命令行的创造性和力量感到很惊讶。
后来,由于项目变化,我致力于用多线程范式编写代码。所使用的编程语言是我钟爱的C或C++,然而,令我惊讶的是,我发现维护一个用C/C++编写的多线程遗留代码库是一项艰巨的任务。这是因为共享状态是随意管理的,一个小错误就可能让我们陷入调试噩梦!
大约在那个时候,我开始了解面向对象设计模式和一些多线程模式。例如,我们希望将一个大的内存数据结构安全地显露给多个线程。我读过有关reader/writer锁模式的内容,该模式使用智能指针(一种C++习语),并据此编写解决方案。
采取此方法后并发错误就消失了!此外,该模式使得线程很容易理解。在我们的示例中,writer线程需要对共享数据结构进行不频繁但独占的访问,reader线程只是将这个结构作为不可变的实体来使用。看啊,没有锁!
没锁带来巨大的好处,随着锁的消失,死锁、竞争和饥饿的可能性也随之消失。感觉真棒!
我在这里得到了一个教训!我得不断学习设计模式,根据不同模式努力思考手边的设计问题。这也帮助我更好地理解代码!最终,我对如何驯服并发这头野兽有了初步的了解!
设计模式是用于解决常见设计问题的可重复使用的解决方案。设计解决方案就是设计模式。你的问题领域可能会有所不同,也就是说,你需要编写的业务逻辑将用于解决你手中的业务问题。但是,一旦使用模式,任务就能很快完成!
例如,当我们使用面向对象范式编写代码时,我们使用“四人组”(GoF)开发的设计模式(http://wiki.c2.com/?DesignPatternsBook)。这本名著为我们提供了一系列设计问题及其解决方案。虽然这种策略模式一直保持不变,但它仍被人们广泛使用。
几年后,我转战到Java领域,并使用ExecutorService接口来构建我的代码。开发代码非常容易,几个月的运行中没有出现任何重大问题。(虽然有一些其他问题,但没有数据冲突,也没有烦琐的调试!)
随后,我进入函数式编程的世界,并开始编写越来越多的Scala程序。这是一个以不变数据结构为标准的新领域,我学到了一种截然不同的范式。
Scala的future模式和actor模式给出了全新的视角。作为程序员,我能感受到这些工具带来的力量。一旦你跨越了认知曲线(诚然在开始时有点畏惧),就能编写许多更安全且经得起推敲的并发代码。
本书讲述了许多并发设计模式,展示了这些模式背后的基本原理,突出了设计方案。
本书目标读者
我们假定你有一定的Java编程基础,理想情况下,你已经用过多线程Java程序,并熟悉“四人组”的设计模式,你还能轻松地通过maven运行Java程序。
本书将带你进入下一个阶段,同时向你展示许多并发模式背后的设计主题。本书希望帮助开发人员通过学习模式来构建可扩展、高性能的应用程序。
本书包含的内容
第1章介绍并发编程。正如你将看到的,并发本身就是一个领域。你将了解UNIX进程以及并发模式的管道和过滤器。本章涉及并发编程的综述,你可能已对这方面有所了解。
第2章涵盖一些关键的基本概念,并介绍Java内存模型的本质。你将了解共享状态模型中出现的竞争条件和问题,并尝试第一个并发模式:手拉手锁定。
第3章包括显式同步可变状态和监视器模式,你会看到这种方法存在很多问题。我们将详细介绍主动对象设计模式。
第4章介绍线程如何通过生产者/消费者模式相互通信,并介绍线程通信的概念,然后解释主/从设计模式。本章还将介绍fork-join模式的一个特例:map-reduce模式。
第5章讨论构建块,还将讨论阻塞队列、有界队列、锁存器、FutureTask、信号量、屏障、激活和安全等内容。最后,描述不可变性以及不可变数据结构固有的线程安全性。
第6章介绍future并讨论它的一元性质,包括转型和单子模式,还将阐释future模式的构成,同时会介绍Promise类。
第7章介绍actor范式。再次回顾主动对象模式,然后解释actor范式,特别是未明确的锁定性质。还将讨论ask与tell、become模式(并强调其不变性)、流水线、半同步或半异步,并通过示例代码进行说明。
读者水平及所需环境
为了充分利用本书,你应该掌握一定水平的Java编程知识和Java线程基础知识,能够使用Java构建工具maven。书中提供了需要复习的重要内容,并通过Java线程示例对此进行补充。
使用诸如IntelliJ Idea、Eclipse或Netbeans等集成开发环境会很有帮助,但并非必须。为了说明函数并发模式,最后两章使用Scala,这两章的代码使用基本的Scala结构。我们建议读者最好浏览一下介绍性的Scala教程,这样做很有益处。
下载示例代码及彩色图像
本书的示例代码及所有截图和样图,可以从http://www.packtpub.com通过个人账号下载,也可以访问华章图书官网http://www.hzbook.com,通过注册并登录个人账号下载。另外还可以从https://github.com/PacktPub
评论
还没有评论。