pageStart 15
-
封面 [1]
-
版权信息 [2]
-
书评 [3]
-
译者序 [5]
-
前言 [6]
-
目录 [10]
-
第1章 简介 1
- 并发简史 1
- 线程的优势 2
- 发挥多处理器的强大能力 2
- 建模的简单性 3
- 异步事件的简化处理 3
- 响应更灵敏的用户界面 4
- 线程带来的风险 4
- 安全性问题 5
- 活跃性问题 7
- 性能问题 7
- 线程无处不在 7
-
第一部分 基础知识 11
-
第2章 线程安全性 11
- 什么是线程安全性 13
- 原子性 14
- 竞态条件 15
- 示例: 延迟初始化中的竞态条件 16
- 复合操作 17
- 加锁机制 18
- 内置锁 20
- 重入 21
- 用锁来保护状态 22
- 活跃性与性能 23
-
第3章 对象的共享 27
- 可见性 27
- 失效数据 28
- 非原子的64位操作 29
- 加锁与可见性 30
- Volatile变量 30
- 发布与逸出 32
- 线程封闭 35
- Ad-hoc线程封闭 35
- 栈封闭 36
- ThreadLocal类 37
- 不变性 38
- Final域 39
- 示例: 使用Volatile类型来发布不可变对象 40
- 安全发布 41
- 不正确的发布: 正确的对象被破坏 42
- 不可变对象与初始化安全性 42
- 安全发布的常用模式 43
- 事实不可变对象 44
- 可变对象 44
- 安全地共享对象 44
- 可见性 27
-
第4章 对象的组合 46
- 设计线程安全的类 46
- 收集同步需求 47
- 依赖状态的操作 48
- 状态的所有权 48
- 实例封闭 49
- Java监视器模式 51
- 示例: 车辆追踪 51
- 线程安全性的委托 53
- 示例: 基于委托的车辆追踪器 54
- 独立的状态变量 55
- 当委托失效时 56
- 发布底层的状态变量 57
- 示例: 发布状态的车辆追踪器 58
- 在现有的线程安全类中添加功能 59
- 客户端加锁机制 60
- 组合 62
- 将同步策略文档化 62
- 设计线程安全的类 46
-
第5章 基础构建模块 66
- 同步容器类 66
- 同步容器类的问题 68
- 迭代器与ConcurrentModificationException 68
- 隐藏迭代器 69
- 并发容器 70
- ConcurrentHashMap 71
- 额外的原子Map操作 72
- CopyOnWriteArrayList 72
- 阻塞队列和生产者-消费者模式 73
- 示例: 桌面搜索 75
- 串行线程封闭 76
- 双端队列与工作密取 77
- 阻塞方法与中断方法 77
- 同步工具类 78
- 闭锁 79
- FutureTask 80
- 信号量 82
- 栅栏 83
- 构建高效且可伸缩的结果缓存 85
- 同步容器类 66
-
第二部分 结构化并发应用程序 93
-
第6章 任务执行 93
- 在线程中执行任务 93
- 串行地执行任务 94
- 显式地为任务创建线程 94
- 无限制创建线程的不足 95
- Executor框架 96
- 示例: 基于Executor的Web服务器 97
- 执行策略 98
- 线程池 98
- Executor的声明周期 99
- 延迟任务与周期任务 101
- 找出可利用的并行性 102
- 示例: 串行的页面渲染器 102
- 携带结果的任务Callable与Future 103
- 示例: 使用CompletionService实现页面渲染器 104
- 在异构任务并行化中存在的局限 106
- CompletionService:Executor与BlockingQueue 106
- 示例: 使用CompletionService实现页面渲染器 107
- 为任务设置时限 108
- 示例: 旅行预定门户网站 109
- 在线程中执行任务 93
-
第7章 取消与关闭 111
- 任务取消 111
- 中断 113
- 中断策略 116
- 响应中断 117
- 示例: 计时运行 118
- 通过Future来实现取消 120
- 处理不可中断的阻塞 121
- 采用newTaskFor来封装非标准的取消 122
- 停止基于线程的服务 124
- 示例: 日志服务 124
- 关闭ExecutorService 127
- "毒丸"对象 128
- 示例: 只执行一次的服务 129
- shutdownNow的局限性 130
- 处理非正常的线程终止 132
- JVM关闭 135
- 关闭钩子 135
- 守护线程 136
- 终结器 136
- 任务取消 111
-
第8章 线程池的使用 138
- 在任务与执行策略之间的隐性耦合 138
- 线程饥饿死锁 139
- 运行时间较长的任务 140
- 设置线程池的大小 140
- 配置ThreadPoolExecutor 141
- 线程的创建与销毁 142
- 管理队列任务 142
- 饱和策略 144
- 线程工厂 146
- 在调用构造函数后再定制ThreadPoolExecutor 147
- 扩展ThreadPoolExecutor 148
- 递归算法的并行化 149
- 在任务与执行策略之间的隐性耦合 138
-
第9章 图形用户界面应用程序 156
- 为什么GUI是单线程的 156
- 串行事件处理 157
- Swing中的线程封闭机制 158
- 短时间的GUI任务 160
- 长时间的GUI任务 161
- 取消 162
- 进度标识和完成标识 163
- SwingWorker 165
- 共享数据模型 165
- 线程安全的数据模型 166
- 分解数据模型 166
- 其他形式的单线程子系统 167
- 为什么GUI是单线程的 156
-
第三部分 活跃性, 性能与测试 169
-
第10章 避免活跃性危险 169
- 死锁 169
- 锁顺序死锁 170
- 动态的锁顺序死锁 171
- 在协作对象之间发生的死锁 174
- 开放调用 175
- 资源死锁 177
- 死锁的避免与诊断 178
- 支持定时的锁 178
- 通过线程转储信息来分析死锁 178
- 其他活跃性危险 180
- 饥饿 180
- 糟糕的响应性 181
- 活锁 181
- 死锁 169
-
第11章 性能与可伸缩性 183
- 对性能的思考 183
- 性能与可伸缩性 184
- 评估各种性能权衡因素 185
- Amdahl定律 186
- 示例: 在各种框架中隐藏的串行部分 188
- Amdahl定律的应用 189
- 线程引入的开销 189
- 上下文切换 190
- 内存同步 190
- 阻塞 192
- 减少锁的竞争 192
- 缩小锁的范围("快进快出") 193
- 减小锁的粒度 195
- 锁分段 196
- 避免热点域 197
- 一些替代独占锁的方法 198
- 监测CPU的利用率 199
- 向对象池说"不" 200
- 示例: 比较Map的性能 200
- 减少上下文切换的开销 201
- 对性能的思考 183
-
第12章 并发程序的测试 204
- 正确性测试 205
- 基本的单元测试 206
- 对阻塞操作的测试 207
- 安全性测试 208
- 资源管理的测试 212
- 使用回调 213
- 产生更多的交替操作 214
- 性能测试 215
- 在PutTakeTest中增加计时功能 215
- 多种算法的比较 217
- 响应性衡量 218
- 避免性能测试的陷阱 220
- 垃圾回收 220
- 动态编译 220
- 对代码路径的不真实采样 222
- 不真实的竞争程度 222
- 无用代码的消除 223
- 其他的测试方法 224
- 代码审查 224
- 静态分析工具 224
- 面向方面的测试技术 226
- 分析与监测工具 226
- 正确性测试 205
-
第四部分 高级主题 227
-
第13章 显式锁 227
- Lock与ReentrantLock 227
- 轮询锁与定时锁 228
- 可中断的锁获取操作 230
- 非块结构的加锁 231
- 性能考虑因素 231
- 公平性 232
- 在synchronized和ReentrantLock之间进行选择 234
- 读-写锁 235
- Lock与ReentrantLock 227
-
第14章 构建自定义的同步工具 238
- 状态依赖性的管理 238
- 示例: 将前提条件的失败传递给调用者 240
- 示例: 通过轮询与休眠来实现简单的阻塞 241
- 条件队列 243
- 使用条件队列 244
- 条件谓词 244
- 过早唤醒 245
- 丢失的信号 246
- 通知 247
- 示例: 阀门类 248
- 子线程的安全问题 249
- 封装条件队列 250
- 入口协议与出口协议 250
- 显式的Condition对象 251
- Synchronizer剖析 253
- AbstractQueuedSynchronizer 254
- java.util.concurrent同步器类中的AQS 257
- ReentrantLock 257
- Semaphore与CountDownLatch 258
- FutureTask 259
- ReentrantReadWriteLock 259
- 状态依赖性的管理 238
-
第15章 原子变量与非阻塞同步机制 261
- 锁的劣势 261
- 硬件对并发的支持 262
- 比较并交换 263
- 非阻塞的计数器 264
- JVM对CAS的支持 265
- 原子变量类 265
- 原子变量是一种"更好的volatile" 266
- 性能比较: 锁与原子变量 267
- 非阻塞算法 270
- 非阻塞的栈 270
- 非阻塞的链表 272
- 原子的域更新器 274
- ABA问题 275
-
第16章 Java内存模型 277
- 什么是内存模型, 为什么需要它 277
- 平台的内存模型 278
- 重排序 278
- Java内存模型简介 280
- 借助同步 281
- 发布 283
- 不安全的发布 283
- 安全的发布 284
- 安全初始化模式 284
- 双重检查加锁 286
- 初始化过程中的安全性 287
- 什么是内存模型, 为什么需要它 277
-
附录A 并发性标注 289
-
参考文献 291