# Java并发编程实战

> 金屋电子书图书详情的 Markdown 版本。

- 规范页面：https://pdfs.top/book/4b600b2198b042df893df199cdc76923
- Markdown 版本：https://pdfs.top/book/4b600b2198b042df893df199cdc76923.md
- 作者：[美] Brian Goetz 等
- 译者：童云兰
- ISBN：9787111370048
- 出版社：机械工业出版社
- 出版日期：2012-01-01
- 语言：中文
- 分类：计算机、编程
- 评分：0
- 可用格式：PDF+EPUB（19.24 MB，290 页）
- 更新时间：2026-08-19 12:16:03

## 下载方式

本站不在 Markdown 页面直接提供文件地址。请前往规范页面，点击对应格式的下载按钮完成下载。

### PDF+EPUB

- 文件格式：PDF+EPUB
- 文件大小：19.24 MB
- 页数：290 页
- 下载说明：请打开规范页面 https://pdfs.top/book/4b600b2198b042df893df199cdc76923，点击 PDF+EPUB 的下载按钮完成下载。


## 内容简介

本书深入浅出地介绍了 Java 线程和并发，是一本完美的 Java 并发参考手册。书中从并发性和线程安全性的基本概念出发，介绍了如何使用类库提供的基本并发构建块，用于避免并发危险、构造线程安全的类及验证线程安全的规则，如何将小的线程安全类组合成更大的线程安全类，如何利用线程来提高并发应用程序的吞吐量，如何识别可并行执行的任务，如何提高单线程子系统的响应性，如何确保并发程序执行预期任务，如何提高并发代码的性能和可伸缩性等内容，最后介绍了一些高级主题，如显式锁、原子变量、非阻塞算法以及如何开发自定义的同步工具类。

本书适合 Java 程序开发人员阅读。

## 目录

- 第1章 简介（第 1 页）
  - 1.1 并发简史（第 1 页）
  - 1.2 线程的优势（第 2 页）
    - 1.2.1 发挥多处理器的强大能力（第 2 页）
    - 1.2.2 建模的简单行（第 3 页）
    - 1.2.3 异步事件的简化处理（第 3 页）
    - 1.2.4 响应更灵敏的用户界面（第 4 页）
  - 1.3 线程带来的风险（第 4 页）
    - 1.4 线程无处不在（第 7 页）
    - 1.3.1 线程安全问题（第 5 页）
    - 1.3.2 活跃性问题（第 7 页）
    - 1.3.3 性能问题（第 7 页）
- 第一部分 基础知识（第 11 页）
  - 第2章 线程安全行（第 11 页）
    - 2.1 什么是线程安全性（第 13 页）
    - 2.2 原子性（第 14 页）
      - 2.2.1 竞态条件（第 15 页）
      - 2.2.2 示例：延迟初始化中的竞态条件（第 16 页）
      - 2.2.3 复合操作（第 17 页）
    - 2.3 加锁机制（第 18 页）
      - 2.3.1 内置锁（第 20 页）
      - 2.3.2 重入（第 21 页）
    - 2.4 用锁来保护状态（第 22 页）
    - 2.5 活跃性与性能（第 23 页）
  - 第3章 对象的共享（第 27 页）
    - 3.1 可见性（第 27 页）
      - 3.1.1 失效数据（第 28 页）
      - 3.1.2 非原子的64位操作（第 29 页）
      - 3.1.3 加锁与可见性（第 30 页）
      - 3.1.4 Volatile 变量（第 30 页）
    - 3.2 发布与逸出（第 32 页）
    - 3.3 线程封闭（第 35 页）
      - 3.3.1 Ad-hoc 线程封闭（第 35 页）
      - 3.3.2 栈封闭（第 36 页）
      - 3.3.3 ThreadLocal类（第 37 页）
    - 3.4 不变性（第 38 页）
      - 3.4.1 Final 域（第 39 页）
      - 3.4.2 示例：使用 Volatile 类型来发布不可变对象（第 40 页）
    - 3.5 安全发布（第 41 页）
      - 3.5.1 不正确的发布：正确的对象被破坏（第 42 页）
      - 3.5.2 不可变对象与初始化安全性（第 42 页）
      - 3.5.3 安全发布的常用模式（第 43 页）
      - 3.5.4 事实不可变对象（第 44 页）
      - 3.5.5 可变对象（第 44 页）
      - 3.5.6 安全地共享对象（第 44 页）
  - 第4章 对象的组合（第 46 页）
    - 4.1 设计线程安全的类（第 46 页）
      - 4.1.1 收集同步需求（第 47 页）
      - 4.1.2 依赖状态的操作（第 48 页）
      - 4.1.3 状态的所有权（第 48 页）
    - 4.2 实例封闭（第 49 页）
      - 4.2.1 Java 监视器模式（第 51 页）
      - 4.2.2 示例：车辆追踪（第 51 页）
    - 4.3 线程安全性的委托（第 53 页）
      - 4.3.1 示例：基于委托的车辆追踪器（第 54 页）
      - 4.3.2 独立的状态变量（第 55 页）
      - 4.3.3 当委托失效时（第 56 页）
      - 4.3.4 发布底层的状态变量（第 57 页）
      - 4.3.5 示例：发布状态的车辆追踪器（第 58 页）
    - 4.4 在现有的线程安全类中添加功能（第 59 页）
      - 4.4.1 客户端加锁机制（第 60 页）
      - 4.4.2 组合（第 62 页）
    - 4.5 将同步策略文档化（第 62 页）
  - 第5章 基础构建模块（第 66 页）
    - 5.1 同步容器类（第 66 页）
      - 5.1.1 同步容器类的问题（第 66 页）
      - 5.1.2 迭代器与 ConcurrentModificationException（第 68 页）
      - 5.1.3 隐藏迭代器（第 69 页）
    - 5.2 并发容器（第 70 页）
      - 5.2.1 ConcurrentHashMap（第 71 页）
      - 5.2.2 额外的原子 Map 操作（第 72 页）
      - 5.2.3 CopyOnWriteArrayList（第 72 页）
    - 5.3 阻塞队列和生产者一消费者模式（第 73 页）
      - 5.3.1 示例：桌面搜索（第 75 页）
      - 5.3.2 串行线程封闭（第 76 页）
      - 5.3.3 双端队列与工作密取（第 77 页）
    - 5.4 阻塞方法与中断方法（第 77 页）
    - 5.5 同步工具类（第 78 页）
      - 5.5.1 闭锁（第 79 页）
      - 5.5.2 FutureTask（第 80 页）
      - 5.5.3 信号量（第 82 页）
      - 5.5.4 栅栏（第 83 页）
    - 5.6 构建高效且可伸缩的结果缓存（第 85 页）
  - 第一部分小结（第 90 页）
- 第二部分 结构化并发应用程序（第 93 页）
  - 第6章 任务执行（第 93 页）
    - 6.1 在线程中执行任务（第 93 页）
      - 6.1.1 串行地执行任务（第 94 页）
      - 6.1.2 显式地为任务创建线程（第 94 页）
      - 6.1.3 无限制创建线程的不足（第 95 页）
    - 6.2 Executor 框架（第 96 页）
      - 6.2.1 示例：基于 Executor 的 Web服务器（第 97 页）
      - 6.2.2 执行策略（第 98 页）
      - 6.2.3 线程池（第 98 页）
      - 6.2.4 Executor 的生命周期（第 99 页）
      - 6.2.5. 延迟任务与周期任务（第 101 页）
    - 6.3 找出可利用的并行性（第 102 页）
      - 6.3.1 示例：串行的页面渲染器（第 102 页）
      - 6.3.2 携带结果的任务Callable 与 Future（第 103 页）
      - 6.3.3 示例：使用 Future 实现页面渲染器（第 104 页）
      - 6.3.4 在异构任务并行化中存在的局限（第 106 页）
      - 6.3.5 CompletionService:Executor 与 BlockingQueue（第 106 页）
      - 6.3.6 示例：使用 CompletionService 实现页面渲染器（第 107 页）
      - 6.3.7 为任务设置时限（第 108 页）
      - 6.3.8 示例：旅行预定门户网站（第 109 页）
      - 小结（第 110 页）
  - 第7章 取消与关闭（第 111 页）
    - 7.1 任务取消（第 111 页）
      - 7.1.1 中断（第 113 页）
      - 7.1.2 中断策略（第 116 页）
      - 7.1.3 响应中断（第 117 页）
      - 7.1.4 示例：计时运行（第 118 页）
      - 7.1.5 通过 Future 来实现取消（第 120 页）
      - 7.1.6 处理不可中断的阻塞（第 121 页）
      - 7.1.7 采用 newTaskFor 来封装非标准的取消（第 122 页）
    - 7.2 停止基于线程的服务（第 124 页）
      - 7.2.1 示例：日志服务（第 124 页）
      - 7.2.2 关闭 ExecutorService（第 127 页）
      - 7.2.3 “毒丸”对象（第 128 页）
      - 7.2.4 示例：只执行一次的服务（第 129 页）
      - 7.2.5 shutdownNow 的局限性（第 130 页）
    - 7.3 处理非正常的线程终止（第 132 页）
    - 7.4 JVM关闭（第 135 页）
      - 7.4.1 关闭钩子（第 135 页）
      - 7.4.2 守护线程（第 136 页）
      - 7.4.3 终结器（第 136 页）
    - 小结（第 137 页）
  - 第8章 线程池的使用（第 138 页）
    - 8.1 在任务与执行策略之间的隐性耦合（第 138 页）
      - 8.1.1 线程饥饿死锁（第 139 页）
      - 8.1.2 运行时间较长的任务（第 140 页）
    - 8.2 设置线程池的大小（第 140 页）
    - 8.3 配置ThreadPoolExecutor（第 141 页）
      - 8.3.1 线程的创建与销毁（第 142 页）
      - 8.3.2 管理队列任务（第 142 页）
      - 8.3.3 饱和策略（第 144 页）
      - 8.3.4 线程工厂（第 146 页）
      - 8.3.5 在调用构造函数后再定制 ThreadPoolExecutor（第 147 页）
    - 8.4 扩展 ThreadPoolExecutor（第 148 页）
    - 8.5 递归算法的并行化（第 149 页）
    - 小结（第 155 页）
  - 第9章 图形用户界面应用程序（第 156 页）
    - 9.1 为什么 GUI是单线程的（第 156 页）
      - 9.1.1 串行事件处理（第 157 页）
      - 9.1.2 Swing 中的线程封闭机制（第 158 页）
    - 9.2 短时间的 GUI 任务（第 160 页）
    - 9.3 长时间的GUI 任务（第 161 页）
      - 9.3.1 取消（第 162 页）
      - 9.3.2 进度标识和完成标识（第 163 页）
      - 9.3.3 SwingWorker（第 165 页）
    - 9.4 共享数据模型（第 165 页）
      - 9.4.1 线程安全的数据模型（第 166 页）
      - 9.4.2 分解数据模型（第 166 页）
    - 9.5 其他形式的单线程子系统（第 167 页）
    - 小结（第 167 页）
- 第三部分 活跃性、性能与测试（第 169 页）
  - 第10章 避免活跃性危险（第 169 页）
    - 10.1 死锁（第 169 页）
      - 10.1.1 锁顺序死锁（第 170 页）
      - 10.1.2 动态的锁顺序死锁（第 171 页）
      - 10.1.3 在协作对象之间发生的死锁（第 174 页）
      - 10.1.4 开放调用（第 175 页）
      - 10.1.5 资源死锁（第 177 页）
    - 10.2 死锁的避免与诊断（第 178 页）
      - 10.2.1 支持定时的锁（第 178 页）
      - 10.2.2 通过线程转储信息来分析死锁（第 178 页）
    - 10.3 其他活跃性危险（第 180 页）
      - 10.3.1 饥饿（第 180 页）
      - 10.3.2 糟糕的响应性（第 181 页）
      - 10.3.3 活锁（第 181 页）
    - 小结（第 182 页）
  - 第11章 性能与可伸缩性（第 183 页）
    - 11.1 对性能的思考（第 183 页）
      - 11.1.1 性能与可伸缩性（第 184 页）
      - 11.1.2 评估各种性能权衡因素（第 185 页）
    - 11.2 Amdahl 定律（第 186 页）
      - 11.2.1 示例：在各种框架中隐藏的串行部分（第 188 页）
      - 11.2.2 Amdahl定律的应用（第 189 页）
    - 11.3 线程引入的开销（第 189 页）
      - 11.3.1 上下文切换（第 190 页）
      - 11.3.2 内存同步（第 190 页）
      - 11.3.3 阻塞（第 192 页）
    - 11.4 减少锁的竞争（第 192 页）
      - 11.4.1 缩小锁的范围（“快进快出”）（第 193 页）
      - 11.4.2 減小锁的粒度（第 195 页）
      - 11.4.3 锁分段（第 196 页）
      - 11.4.4 避免热点域（第 197 页）
      - 11.4.5 一些替代独占锁的方法（第 198 页）
      - 11.4.6 监测CPU 的利用率（第 199 页）
      - 11.4.7 向对象池说“不”（第 200 页）
    - 11.5 示例：比较 Map 的性能（第 200 页）
    - 11.6 减少上下文切换的开销（第 201 页）
    - 小结（第 203 页）
  - 第12章 并发程序的测试（第 204 页）
    - 12.1 正确性测试（第 205 页）
      - 12.1.1 基本的单元测试（第 206 页）
      - 12.1.2 对阻塞操作的测试（第 207 页）
      - 12.1.3 安全性测试（第 208 页）
      - 12.1.4 资源管理的测试（第 212 页）
      - 12.1.5 使用回调（第 213 页）
      - 12.1.6 产生更多的交替操作（第 214 页）
    - 12.2 性能测试（第 215 页）
      - 12.2.1 在 PutTakeTest 中增加计时功能（第 215 页）
      - 12.2.2 多种算法的比较（第 217 页）
      - 12.2.3 响应性衡量（第 218 页）
    - 12.3 避免性能测试的陷阱（第 220 页）
      - 12.3.1 垃圾回收（第 220 页）
      - 12.3.2 动态编译（第 220 页）
      - 12.3.3 对代码路径的不真实采样（第 222 页）
      - 12.3.4 不真实的竞争程度（第 222 页）
      - 12.3.5 无用代码的消除（第 223 页）
    - 12.4 其他的测试方法（第 224 页）
      - 12.4.1 代码审查（第 224 页）
      - 12.4.2 静态分析工具（第 224 页）
      - 12.4.3 面向方面的测试技术（第 226 页）
      - 12.4.4 分析与监测工具（第 226 页）
      - 小结（第 226 页）
- 第四部分 高级主题（第 227 页）
  - 第13章 显式锁（第 227 页）
    - 13.1 Lock 与 ReentrantLock（第 227 页）
      - 13.1.1 轮询锁与定时锁（第 228 页）
      - 13.1.2 可中断的锁获取操作（第 230 页）
      - 13.1.3 非块结构的加锁（第 231 页）
    - 13.2 性能考虑因素（第 231 页）
    - 13.3 公平性（第 232 页）
    - 13.4 在 synchronized 和 ReentrantLock 之间进行选择（第 234 页）
    - 13.5 读一写锁（第 235 页）
    - 小结（第 237 页）
  - 第14章 构建自定义的同步工具（第 238 页）
    - 14.1 状态依赖性的管理（第 238 页）
      - 14.1.1 示例：将前提条件的失败传递给调用者（第 240 页）
      - 14.1.2 示例：通过轮询与休眠来实现简单的阻塞（第 241 页）
      - 14.1.3 条件队列（第 243 页）
    - 14.2 使用条件队列（第 244 页）
      - 14.2.1 条件谓词（第 244 页）
      - 14.2.2 过早唤醒（第 245 页）
      - 14.2.3 丟失的信号（第 246 页）
      - 14.2.4 通知（第 247 页）
      - 14.2.5 示例：阀门类（第 248 页）
      - 14.2.6 子类的安全问题（第 249 页）
      - 14.2.7 封装条件队列（第 250 页）
      - 14.2.8 入口协议与出口协议（第 250 页）
    - 14.3 显式的 Condition 对象（第 251 页）
    - 14.4 •Synchronizer 剖析（第 253 页）
    - 14.5 AbstractQueuedSynchronizer（第 254 页）
    - 14.6 java.util.concurrent 同步器类中的AQS（第 257 页）
      - 14.6.1 ReentrantLock（第 257 页）
      - 14.6.2 Semaphore 与 CountDownLatch（第 258 页）
      - 14.6.3 FutureTask（第 259 页）
      - 14.6.4 ReentrantReadWriteLock（第 259 页）
    - 小结（第 260 页）
  - 第15章 原子变量与非阻塞同步机制（第 261 页）
    - 15.1 锁的劣势（第 261 页）
    - 15.2 硬件对并发的支持（第 262 页）
      - 15.2.1 比较并交换（第 263 页）
      - 15.2.2 非阻塞的计数器（第 264 页）
      - 15.2.3 JVM对 CAS的支持（第 265 页）
    - 15.3 原子变量类（第 265 页）
      - 15.3.1 原子变量是一种“更好的 volatile”（第 266 页）
      - 15.3.2 性能比较：锁与原子变量（第 267 页）
    - 15.4 非阻塞算法（第 270 页）
      - 15.4.1 非阻塞的栈（第 270 页）
      - 15.4.2 非阻塞的链表（第 272 页）
      - 15.4.3 原子的域更新器（第 274 页）
      - 15.4.4 ABA 问题（第 275 页）
    - 小结（第 276 页）
  - 第16章 Java内存模型（第 277 页）
    - 16.1 什么是内存模型，为什么需要它（第 277 页）
      - 16.1.1 平台的内存模型（第 278 页）
      - 16.1.2 重排序（第 278 页）
      - 16.1.3 Java 内存模型简介（第 280 页）
      - 16.1.4 借助同步（第 281 页）
    - 16.2 发布（第 283 页）
      - 16.2.1 不安全的发布（第 283 页）
      - 16.2.2 安全的发布（第 284 页）
      - 16.2.3 安全初始化模式（第 284 页）
      - 16.2.4 双重检查加锁（第 286 页）
    - 16.3 初始化过程中的安全性（第 287 页）
    - 小结（第 288 页）
- 附录A 并发性标注（第 289 页）
  - A.1 类的标注（第 289 页）
  - A.2 域和方法的标注（第 289 页）
- 参考文献（第 291 页）
