| 作者 |
| 汪文君 方腾飞 魏鹏 程晓明 Brian Goetz Tim Peierls |
| 丛书名 |
| Java核心技术系列 |
| 出版社 |
| 机械工业出版社 |
| ISBN |
| 9782007071059 |
| 简要 |
| 简介 |
| 内容简介书籍计算机书籍 ---------------------------Java高并发编程详解:深入理解并发核心库--------------------------- 本书共包含四大部分,其中,第一部分(第1章)详细介绍了JMH(Java Micro benchmark Harness)基准测试工具的使用细节。该工具是由Oracle JVM开发团队相关成员开发的,借助它,开发者将能足够了解自己所编写的程序代码,以及程序在运行期的精确性能表现。在本书的其他章节对API之间的性能进行对比时,主要也是依赖于该工具,因此在学习本书的其他章节时,最好能够掌握该部分内容,强烈推荐开发者将JMH纳入自己日常的“兵器库”中,以便能够随时随地进行利用。 第二部分主要围绕Java并发包进行展开,涉及的内容包括Java的原子类型及其底层原理(第2章);Java的并发工具集(第3章),其中还穿插了Google Guava的部分内容;Java的并发容器(第4章),包括阻塞队列BlockingQueue和并发容器等内容;Java的ExecutorService(第5章),以及Future家族成员的详解。 第三部分(第6章),主要介绍自Java 8 引入的Stream,并且重点解释了具备高并发能力的并行流原理,以及如何自定义并行流等相关内容。 第四部分(第7章),深入讲解Metrics,它作为一个比较小巧的度量工具集,目前已经成为事实上的度量标准,在很多开源软件、框架和平台中都能看到对它的使用,比如Apache的Kafka、Spark、Storm、Spring Cloud等都是使用Metrics作为系统运行性能指标收集的手段。 ---------------------------Java高并发编程详解:多线程与架构设计--------------------------- 本书主要包含四个部分: 部分主要阐述Thread的基础知识,详细介绍线程的API使用、线程安全、线程间数据通信,以及如何保护共享资源等内容,它是深入学习多线程内容的基础。 第二部分引入了ClassLoader,这是因为ClassLoader与线程不无关系,我们可以通过synchronized关键字,或者Lock等显式锁的方式在代码的编写阶段对共享资源进行数据一致性保护,那么一个Class在完成初始化的整个过程到后在方法区(JDK8 以后在元数据空间)其数据结构是怎样确保数据一致性的呢?这就需要对ClassLoader有一个比较全面的认识和了解。 第三部分详细、深入地介绍volatile关键字的语义,volatile关键字在Java中非常重要,可以说它奠定了Java核心并发包的高效运行,在这一部分中,我们通过实例展示了如何使用volatile关键字以及非常详细地介绍了Java内存模型等知识。 本书的第四部分,站在程序架构设计的角度深入讲解了如何设计高效灵活的多线程应用程序,这一部分长达15个章节,其重要程度可见一斑。 . ---------------------------Java并发编程的艺术--------------------------- 并发编程领域的扛鼎之作,作者是阿里和1号店的资深Java技术专家,对并发编程有非常深入的研究,本书是他们多年一线开发经验的结晶。本书的部分内容在出版早期发表在Java并发编程网和帅foQ等技术社区,得到了非常高的评价。它选取了Java并发编程中最核心的技术进行讲解,从JDK源码、JVM、CPU等多角度全面剖析和讲解了Java并发编程的框架、工具、原理和方法,对Java并发编程进行了最为深入和透彻的阐述。 内容涵盖Java并发编程机制的底层实现原理、Java内存模型、Java并发编程基础、Java中的锁、并发容器和框架、原子类、并发工具类、线程池、Executor框架等主题,每个主题都做了深入的讲解,同时通过实例介绍了如何应用这些技术。 ---------------------------Java并发编程实战--------------------------- 《Java并发编程实战》深入浅出地介绍了Java线程和并发,是一本完美的Java并发参考手册。书中从并发性和线程安全性的基本概念出发,介绍了如何使用类库提供的基本并发构建块,用于避免并发危险、构造线程安全的类及验证线程安全的规则,如何将小的线程安全类组合成更大的线程安全类,如何利用线程来提高并发应用程序的吞吐量,如何识别可并行执行的任务,如何提高单线程子系统的响应性,如何确保并发程序执行预期任务,如何提高并发代码的性能和可伸缩性等内容,最后介绍了一些高级主题,如显式锁、原子变量、非阻塞算法以及如何开发自定义的同步工具类。 《Java并发编程实战》适合Java程序开发人员阅读。 |
| 目录 |
---------------------------Java高并发编程详解:深入理解并发核心库--------------------------- 推荐序一 推荐序二 推荐序三 推荐序四 前 言 第1章 JMH 1 1.1 JMH简介 1 1.2 JMH快速入门 1 1.2.1 用main方法进行测试 1 1.2.2 用JMH进行微基准测试 3 1.3 JMH的基本用法 6 1.3.1 @Benchmark标记基准测试方法 7 1.3.2 Warmup以及Measurement 8 1.3.3 四大BenchmarkMode 10 1.3.4 OutputTimeUnit 14 1.3.5 三大State的使用 14 1.3.6 @Param的妙用 19 1.3.7 JMH的测试套件(Fixture) 23 1.3.8 CompilerControl 26 1.4 编写正确的微基准测试以及高级用法 27 1.4.1 编写正确的微基准测试用例 28 1.4.2 一些高级的用法 38 1.5 JMH的Profiler 45 1.5.1 StackProfiler 45 1.5.2 GcProfiler 47 1.5.3 ClassLoaderProfiler 51 1.5.4 CompilerProfiler 54 1.6 本章总结 56 第2章 Java并发包之原子类型详解 57 2.1 AtomicInteger详解 58 2.1.1 性能测试对比 58 2.1.2 AtomicInteger的基本用法 61 2.1.3 AtomicInteger内幕 66 2.1.4 AtomicInteger总结 68 2.2 AtomicBoolean详解 69 2.2.1 AtomicBoolean的基本用法 69 2.2.2 AtomicBoolean内幕 71 2.2.3 Try Lock显式锁的实现 71 2.2.4 AtomicBoolean总结 74 2.3 AtomicLong详解 74 2.4 AtomicReference详解 76 2.4.1 AtomicReference的应用场景 77 2.4.2 AtomicReference的基本用法 83 2.4.3 AtomicReference的内幕 84 2.4.4 AtomicReference总结 86 2.5 AtomicStampedReference详解 86 2.5.1 CAS算法ABA问题 86 2.5.2 AtomicStampedReference详解 87 2.5.3 AtomicStampedReference总结 89 2.6 AtomicArray详解 89 2.7 AtomicFieldUpdater详解 90 2.7.1 原子性更新对象属性 90 2.7.2 注意事项 91 2.7.3 AtomicFieldUpdater总结 93 2.8 sun.misc.Unsafe详解 93 2.8.1 如何获取Unsafe 94 2.8.2 JNI、Java和C/C++混合编程 95 2.8.3 危险的Unsafe 98 2.8.4 sun.misc.Unsafe总结 100 2.9 本章总结 100 第3章 Java并发包之工具类详解 102 3.1 CountDownLatch工具详解 102 3.1.1 等待所有子任务结束 103 3.1.2 CountDownLatch的其他方法及总结 106 3.2 CyclicBarrier工具详解 107 3.2.1 等待所有子任务结束 107 3.2.2 CyclicBarrier的循环特性 110 3.2.3 CyclicBarrier的其他方法以及总结 114 3.2.4 CyclicBarrier VS. CountDownLatch 116 3.3 Exchanger工具详解 116 3.3.1 一对线程间的数据交换 116 3.3.2 Exchanger的方法详解 121 3.3.3 Exchanger总结 123 3.4 Semaphore工具详解 124 3.4.1 Semaphore限制同时在线的用户数量 124 3.4.2 使用Semaphore定义try lock 127 3.4.3 Semaphore其他方法详解 129 3.4.4 扩展Semaphore增强release 135 3.4.5 Semaphore总结 138 3.5 Phaser工具详解 138 3.5.1 Phaser的基本用法 138 3.5.2 Phase(阶段)以及Phaser方法详解 144 3.5.3 Phaser层级关系 148 3.5.4 Phaser总结 149 3.6 Lock&ReentrantLock详解 150 3.6.1 Lock及ReentrantLock方法详解 150 3.6.2 正确使用显式锁Lock 152 3.6.3 ReentrantLock VS. Synchronized关键字 158 3.6.4 显式锁Lock总结 164 3.7 ReadWriteLock&ReentrantRead-WriteLock详解 165 3.7.1 读写锁的基本使用方法 165 3.7.2 读写锁的方法 167 3.7.3 基准测试性能对比 167 3.7.4 读写锁总结 170 3.8 Condition详解 171 3.8.1 初识Condition 171 3.8.2 Condition接口方法详解 174 3.8.3 使用Condition之生产者消费者 177 3.8.4 Condition总结 181 3.9 StampedLock详解 181 3.9.1 读写锁的饥饿写问题 182 3.9.2 StampedLock的使用 183 3.9.3 与其他锁的性能对比 185 3.9.4 StampedLock总结 191 3.10 Guava之Monitor详解 192 3.10.1 Monitor及Guard 192 3.10.2 Monitor的其他方法 194 3.10.3 Monitor总结 194 3.11 Guava之RateLimiter详解 194 3.11.1 RateLimiter的基本使用 195 3.11.2 RateLimiter的限流操作——漏桶算法 196 3.11.3 令牌环桶算法 201 3.11.4 RateLimiter总结 204 3.12 本章总结 204 第4章 Java并发包之并发容器详解 205 4.1 链表 206 4.1.1 基本的链表 206 4.1.2 优先级链表 210 4.1.3 跳表(SkipList) 213 4.1.4 链表总结 221 4.2 BlockingQueue(阻塞队列) 221 4.2.1 ArrayBlockingQueue 222 4.2.2 PriorityBlockingQueue 226 4.2.3 LinkedBlockingQueue 228 4.2.4 DelayQueue 228 4.2.5 SynchronousQueue 231 4.2.6 LinkedBlockingDeque 233 4.2.7 LinkedTransferQueue 234 4.2.8 BlockingQueue总结 236 4.3 ConcurrentQueue(并发队列) 237 4.3.1 并发队列的性能 239 4.3.2 并发队列在使用中需要注意的问题 241 4.3.3 并发队列总结 245 4.4 ConcurrentMap(并发映射) 245 4.4.1 ConcurrentHashMap简介 245 4.4.2 ConcurrentSkipListMap简介 247 4.4.3 并发映射总结 247 4.5 写时拷贝算法(Copy On Write) 248 4.5.1 CopyOnWrite读实现操作分析 249 4.5.2 CopyOnWrite写实现操作分析 249 4.5.3 CopyOnWrite总结 250 4.6 高并发无锁(Lock Free)数据结构的实现 250 4.6.1 高并发无锁链表的实现 250 4.6.2 Lock Free数据结构的测试 253 4.6.3 本节总结 255 4.7 本章总结 255 第5章 Java并发包之ExecutorService详解 256 5.1 Executor&ExecutorService详解 256 5.1.1 ThreadPoolExecutor详解 257 5.1.2 ScheduledExecutorService详解 265 5.1.3 关闭ExecutorService 271 5.1.4 Executors详解 273 5.1.5 ExecutorService总结 276 5.2 Future和Callback 277 5.2.1 Future详解 277 5.2.2 ExecutorService与Future 280 5.2.3 Future的不足之处 282 5.2.4 Google Guava的Future 282 5.2.5 Future总结 284 5.3 ForkJoinPool 详解 284 5.3.1 Fork/Join Framework介绍 284 5.3.2 ForkJoinTask详解 285 5.3.3 ForkJoinPool总结 289 5.4 CompletionService详解 289 5.4.1 ExecutorService执行批量任务的缺陷 289 5.4.2 CompletionService详解 291 5.4.3 CompletionService总结 294 5.5 CompletableFuture详解 294 5.5.1 CompletableFuture的基本用法 294 5.5.2 任务的异步运行 296 5.5.3 异步任务链 296 5.5.4 合并多个Future 298 5.5.5 多Future的并行计算 299 5.5.6 错误处理 299 5.5.7 JDK 9对CompletableFuture的进一步支持 300 5.5.8 CompletableFuture总结 300 5.6 本章总结 301 第6章 Java Streams详解 302 6.1 Stream介绍及其基本操作 302 6.1.1 如何创建Stream 303 6.1.2 Stream之Intermediate操作 306 6.1.3 Stream之Terminal操作 312 6.1.4 NumericStream详解 317 6.1.5 Stream总结 320 6.2 Collector在Stream中的使用 320 6.2.1 初识Collector 321 6.2.2 Collectors用法详解 324 6.2.3 自定义Collector 335 6.2.4 Collector总结 336 6.3 Parallel Stream详解 337 6.3.1 并行流Parallel Stream 337 6.3.2 Spliterator 详解 340 6.3.3 Spliterator总结 343 6.4 本章总结 344 第7章 Metrics(Powerful Toolkit For Measure) 345 7.1 Metrics快速入门 345 7.1.1 如何监控度量应用程序 345 7.1.2 Metrics环境搭建 346 7.2 五大Metric详解 346 7.2.1 Meter 347 7.2.2 Gauge 349 7.2.3 Counter 360 7.2.4 Histogram 362 7.2.5 Timer 370 7.3 Reporter详解 372 7.3.1 ConsoleReporter 373 7.3.2 LogReporter 376 7.3.3 JMXReporter 378 7.3.4 CsvReporter 379 7.4 Metrics Plugins 380 7.4.1 Health Check 381 7.4.2 JVM Instrumentation 386 7.5 深入Metrics源码 387 7.5.1 MetricRegistry如何工作 388 7.5.2 Reporter如何工作 392 7.5.3 拾遗补漏 394 7.6 本章总结 396 ---------------------------Java高并发编程详解:多线程与架构设计--------------------------- 推荐序一 推荐序二 推荐序三 推荐序四 前言 第一部分 多线程基础 第1章 快速认识线程 3 1.1 线程的介绍 3 1.2 快速创建并启动一个线程 3 1.2.1 尝试并行运行 4 1.2.2 并发运行交替输出 5 1.2.3 使用Jconsole观察线程 6 1.3 线程的生命周期详解 7 1.3.1 线程的NEW状态 8 1.3.2 线程的RUNNABLE状态 8 1.3.3 线程的 RUNNING状态 8 1.3.4 线程的BLOCKED状态 8 1.3.5 线程的TERMINATED状态 9 1.4 线程的start方法剖析:模板设计模式在Thread中的应用 9 1.4.1 Thread start方法源码分析以及注意事项 9 1.4.2 模板设计模式在Thread中的应用 11 1.4.3 Thread模拟营业大厅叫号机程序 13 1.5 Runnable接口的引入以及策略模式在Thread中的使用 16 1.5.1 Runnable的职责 16 1.5.2 策略模式在Thread中的应用 16 1.5.3 模拟营业大厅叫号机程序 18 1.6 本章总结 19 第2章 深入理解Thread构造函数 20 2.1 线程的命名 20 2.1.1 线程的默认命名 21 2.1.2 命名线程 21 2.1.3 修改线程的名字 22 2.2 线程的父子关系 22 2.3 Thread与ThreadGroup 23 2.4 Thread与Runnable 24 2.5 Thread与JVM虚拟机栈 25 2.5.1 Thread与Stacksize 25 2.5.2 JVM内存结构 27 2.5.3 Thread与虚拟机栈 30 2.6 守护线程 33 2.6.1 什么是守护线程 33 2.6.2 守护线程的作用 34 2.7 本章总结 34 第3章 Thread API的详细介绍 35 3.1 线程sleep 35 3.1.1 sleep方法介绍 35 3.1.2 使用TimeUnit替代Thread.sleep 36 3.2 线程yield 37 3.2.1 yield方法介绍 37 3.2.2 yield和sleep 37 3.3 设置线程的优先级 38 3.3.1 线程优先级介绍 38 3.3.2 线程优先级源码分析 39 3.3.3 关于优先级的一些总结 40 3.4 获取线程ID 40 3.5 获取当前线程 41 3.6 设置线程上下文类加载器 41 3.7 线程interrupt 42 3.7.1 interrupt 42 3.7.2 isInterrupted 43 3.7.3 interrupted 45 3.7.4 interrupt注意事项 46 3.8 线程join 47 3.8.1 线程join方法详解 48 3.8.2 join方法结合实战 50 3.9 如何关闭一个线程 53 3.9.1 正常关闭 54 3.9.2 异常退出 56 3.9.3 进程假死 56 3.10 本章总结 58 第4章 线程安全与数据同步 59 4.1 数据同步 59 4.1.1 数据不一致问题的引入 59 4.1.2 数据不一致问题原因分析 61 4.2 初识 synchronized关键字 62 4.2.1 什么是synchronized 63 4.2.2 synchronized关键字的用法 63 4.3 深入synchronized关键字 65 4.3.1 线程堆栈分析 65 4.3.2 JVM指令分析 67 4.3.3 使用synchronized需要注意的问题 70 4.4 This Monitor和Class Monitor的详细介绍 72 4.4.1 this monitor 72 4.4.2 class monitor 74 4.5 程序死锁的原因以及如何诊断 77 4.5.1 程序死锁 77 4.5.2 程序死锁举例 77 4.5.3 死锁诊断 80 4.6 本章总结 81 第5章 线程间通信 82 5.1 同步阻塞与异步非阻塞 82 5.1.1 同步阻塞消息处理 82 5.1.2 异步非阻塞消息处理 83 5.2 单线程间通信 84 5.2.1 初识wait和notify 84 5.2.2 wait和notify方法详解 87 5.2.3 关于wait和notify的注意事项 89 5.2.4 wait和sleep 90 5.3 多线程间通信 90 5.3.1 生产者消费者 90 5.3.2 线程休息室wait set 93 5.4 自定义显式锁BooleanLock 94 5.4.1 synchronized关键字的缺陷 94 5.4.2 显式锁BooleanLock 95 5.5 本章总结 104 第6章 ThreadGroup详细讲解 105 6.1 ThreadGroup与Thread 105 6.2 创建ThreadGroup 105 6.3 复制Thread数组和ThreadGroup数组 106 6.3.1 复制Thread数组 106 6.3.2 复制ThreadGroup数组 109 6.4 ThreadGroup操作 109 6.4.1 ThreadGroup的基本操作 110 6.4.2 ThreadGroup的interrupt 113 6.4.3 ThreadGroup的destroy 114 6.4.4 守护ThreadGroup 115 6.5 本章总结 116 第7章 Hook线程以及捕获线程执行异常 117 7.1 获取线程运行时异常 117 7.1.1 UncaughtExceptionHandler的介绍 117 7.1.2 UncaughtExceptionHandler实例 118 7.1.3 UncaughtExceptionHandler源码分析 119 7.2 注入钩子线程 121 7.2.1 Hook线程介绍 121 7.2.2 Hook线程实战 122 7.2.3 Hook线程应用场景以及注意事项 124 7.3 本章总结 124 第8章 线程池原理以及自定义线程池 125 8.1 线程池原理 125 8.2 线程池实现 126 8.2.1 线程池接口定义 127 8.2.2 线程池详细实现 131 8.3 线程池的应用 139 8.4 本章总结 142 第二部分 Java ClassLoader 第9章 类的加载过程 144 9.1 类的加载过程简介 144 9.2 类的主动使用和被动使用 145 9.3 类的加载过程详解 148 9.3.1 类的加载阶段 148 9.3.2 类的连接阶段 149 9.3.3 类的初始化阶段 154 9.4 本章总结 156 第10章 JVM类加载器 158 10.1 JVM内置三大类加载器 158 10.1.1 根类加载器介绍 159 10.1.2 扩展类加载器介绍 159 10.1.3 系统类加载器介绍 160 10.2 自定义类加载器 161 10.2.1 自定义类加载器,问候世界 161 10.2.2 双亲委托机制详细介绍 165 10.2.3 破坏双亲委托机制 167 10.2.4 类加载器命名空间、运行时包、类的卸载等 170 10.3 本章总结 175 第11章 线程上下文类加载器 177 11.1 为什么需要线程上下文类加载器 177 11.2 数据库驱动的初始化源码分析 178 11.3 本章总结 180 第三部分 深入理解volatile关键字 第12章 volatile关键字的介绍 182 12.1 初识volatile关键字 182 12.2 机器硬件CPU 184 12.2.1 CPU Cache模型 184 12.2.2 CPU缓存一致性问题 186 12.3 Java内存模型 187 12.4 本章总结 188 第13章 深入volatile关键字 189 13.1 并发编程的三个重要特性 189 13.1.1 原子性 189 13.1.2 可见性 190 13.1.3 有序性 190 13.2 JMM如何保证三大特性 191 13.2.1 JMM与原子性 192 13.2.2 JMM与可见性 193 13.2.3 JMM与有序性 194 13.3 volatile关键字深入解析 195 13.3.1 volatile关键字的语义 195 13.3.2 volatile的原理和实现机制 197 13.3.3 volatile的使用场景 198 13.3.4 volatile和synchronized 199 13.4 本章总结 200 第14章 7种单例设计模式的设计 201 14.1 饿汉式 201 14.2 懒汉式 202 14.3 懒汉式+同步方法 203 14.4 Double-Check 204 14.5 Volatile+Double-Check 206 14.6 Holder方式 206 14.7 枚举方式 207 14.8 本章总结 208 第四部分 多线程设计架构模式 第15章 监控任务的生命周期 212 15.1 场景描述 212 15.2 当观察者模式遇到Thread 212 15.2.1 接口定义 212 15.2.2 ObservableThread实现 215 15.3 本章总结 217 15.3.1 测试运行 217 15.3.2 关键点总结 219 第16章 Single Thread Execution设计模式 220 16.1 机场过安检 220 16.1.1 非线程安全 221 16.1.2 问题分析 223 16.1.3 线程安全 225 16.2 吃面问题 225 16.2.1 吃面引起的死锁 226 16.2.2 解决吃面引起的死锁问题 228 16.2.3 哲学家吃面 229 16.3 本章总结 230 第17章 读写锁分离设计模式 231 17.1 场景描述 231 17.2 读写分离程序设计 232 17.2.1 接口定义 232 17.2.2 程序实现 234 17.3 读写锁的使用 239 17.4 本章总结 242 第18章 不可变对象设计模式 244 18.1 线程安全性 244 18.2 不可变对象的设计 244 18.2.1 非线程安全的累加器 245 18.2.2 方法同步增加线程安全性 247 18.2.3 不可变的累加器对象设计 248 18.3 本章总结 249 第19章 Future设计模式 251 19.1 先给你一张凭据 251 19.2 Future设计模式实现 251 19.2.1 接口定义 252 19.2.2 程序实现 253 19.3 Future的使用以及技巧总结 256 19.4 增强FutureService使其支持回调 257 19.5 本章总结 258 第20章 Guarded Suspension设计模式 259 20.1 什么是Guarded Suspension设计模式 259 20.2 Guarded Suspension的示例 259 20.3 本章总结 261 第21章 线程上下文设计模式 262 21.1 什么是上下文 262 21.2 线程上下文设计 263 21.3 ThreadLocal详解 264 21.3.1 ThreadLocal的使用场景及注意事项 265 21.3.2 ThreadLocal的方法详解及源码分析 265 21.3.3 ThreadLocal的内存泄漏问题分析 270 21.4 使用ThreadLocal设计线程上下文 274 21.5 本章总结 276 第22章 Balking设计模式 277 22.1 什么是Balking设计 277 22.2 Balking模式之文档编辑 278 22.2.1 Document 278 22.2.2 AutoSaveThread 280 22.2.3 DocumentEditThread 281 22.3 本章总结 283 第23章 Latch设计模式 284 23.1 什么是Latch 284 23.2 CountDownLatch程序实现 285 23.2.1 无限等待的Latch 285 23.2.2 有超时设置的Latch 289 23.3 本章总结 291 第24章 Thread-Per-Message设计模式 293 24.1 什么是Thread-Per-Message模式 293 24.2 每个任务一个线程 293 24.3 多用户的网络聊天 296 24.3.1 服务端程序 296 24.3.2 响应客户端连接的Handler 297 24.3.3 聊天程序测试 299 24.4 本章总结 300 第25章 Two Phase Termination设计模式 301 25.1 什么是Two Phase Termination模式 301 25.2 Two Phase Termination的示例 302 25.2.1 线程停止的Two Phase Termination 302 25.2.2 进程关闭的Two Phase Termination 303 25.3 知识扩展 304 25.3.1 Strong Reference及LRUCache 304 25.3.2 Soft Reference及SoftLRUCache 308 25.3.3 Weak Reference 311 25.3.4 Phantom Reference 312 25.4 本章总结 314 第26章 Worker-Thread设计模式 315 26.1 什么是Worker-Thread模式 315 26.2 Worker-Thread模式实现 315 26.2.1 产品及组装说明书 316 26.2.2 流水线传送带 317 26.2.3 流水线工人 319 26.3 本章总结 320 26.3.1 产品流水线测试 320 26.3.2 Worker-Thread和Producer-Consumer 321 第27章 Active Objects设计模式 323 27.1 接受异步消息的主动对象 323 27.2 标准Active Objects模式设计 323 27.2.1 OrderService接口设计 325 27.2.2 OrderServiceImpl 详解 325 27.2.3 OrderServiceProxy详解 326 27.2.4 MethodMessage 328 27.2.5 ActiveMessageQueue 330 27.2.6 OrderServiceFactory及测试 332 27.3 通用Active Objects框架设计 333 27.3.1 ActiveMessage详解 334 27.3.2 @ActiveMethod 336 27.3.3 ActiveServiceFactory详解 337 27.3.4 ActiveMessageQueue及其他 339 27.4 本章总结 341 第28章 Event Bus设计模式 342 28.1 Event Bus设计 343 28.1.1 Bus接口详解 343 28.1.2 同步EventBus详解 345 28.1.3 异步EventBus详解 347 28.1.4 Subscriber注册表Registry详解 348 28.1.5 Event广播Dispatcher详解 350 28.1.6 其他类接口设计 353 28.1.7 Event Bus测试 355 28.2 Event Bus实战——监控变化 357 28.2.1 WatchService遇到EventBus 357 28.2.2 FileChangeEvent 359 28.2.3 监控变化 359 28.3 本章总结 360 第29章 Event Driven设计模式 361 29.1 Event-Driven Architecture基础 361 29.1.1 Events 361 29.1.2 Event Handlers 362 29.1.3 Event Loop 363 29.2 开发一个Event-Driven框架 364 29.2.1 同步EDA框架设计 364 29.2.2 异步EDA框架设计 370 29.3 Event-Driven的使用 375 29.3.1 Chat Event 375 29.3.2 Chat Channel(Handler) 376 29.3.3 Chat User线程 377 29.4 本章总结 379 ---------------------------Java并发编程的艺术--------------------------- 前 言 第1章 并发编程的挑战 1 1.1 上下文切换 1 1.1.1 多线程一定快吗 1 1.1.2 测试上下文切换次数和时长 3 1.1.3 如何减少上下文切换 3 1.1.4 减少上下文切换实战 4 1.2 死锁 5 1.3 资源限制的挑战 6 1.4 本章小结 7 第2章 Java并发机制的底层实现原理 8 2.1 volatile的应用 8 2.2 synchronized的实现原理与应用 11 2.2.1 Java对象头 12 2.2.2 锁的升级与对比 13 2.3 原子操作的实现原理 16 2.4 本章小结 20 第3章 Java内存模型 21 3.1 Java内存模型的基础 21 3.1.1 并发编程模型的两个关键问题 21 3.1.2 Java内存模型的抽象结构 22 3.1.3 从源代码到指令序列的重排序 23 3.1.4 并发编程模型的分类 24 3.1.5 happens-before简介 26 3.2 重排序 27 3.2.1 数据依赖性 28 3.2.2 as-if-serial语义 28 3.2.3 程序顺序规则 29 3.2.4 重排序对多线程的影响 29 3.3 顺序一致性 31 3.3.1 数据竞争与顺序一致性 31 3.3.2 顺序一致性内存模型 32 3.3.3 同步程序的顺序一致性效果 34 3.3.4 未同步程序的执行特性 35 3.4 volatile的内存语义 38 3.4.1 volatile的特性 38 3.4.2 volatile写-读建立的happens-before关系 39 3.4.3 volatile写-读的内存语义 40 3.4.4 volatile内存语义的实现 42 3.4.5 JSR-133为什么要增强volatile的内存语义 46 3.5 锁的内存语义 47 3.5.1 锁的释放-获取建立的 happens-before关系 47 3.5.2 锁的释放和获取的内存语义 48 3.5.3 锁内存语义的实现 50 3.5.4 concurrent包的实现 54 3.6 final域的内存语义 55 3.6.1 final域的重排序规则 55 3.6.2 写final域的重排序规则 56 3.6.3 读final域的重排序规则 57 3.6.4 final域为引用类型 58 3.6.5 为什么final引用不能从构造函数内“溢出” 59 3.6.6 final语义在处理器中的实现 61 3.6.7 JSR-133为什么要增强final的语义 62 3.7 happens-before 62 3.7.1 JMM的设计 62 3.7.2 happens-before的定义 64 3.7.3 happens-before规则 65 3.8 双重检查锁定与延迟初始化 67 3.8.1 双重检查锁定的由来 67 3.8.2 问题的根源 69 3.8.3 基于volatile的解决方案 71 3.8.4 基于类初始化的解决方案 72 3.9 Java内存模型综述 78 3.9.1 处理器的内存模型 78 3.9.2 各种内存模型之间的关系 80 3.9.3 JMM的内存可见性保证 80 3.9.4 JSR-133对旧内存模型的修补 81 3.10 本章小结 82 第4章 Java并发编程基础 83 4.1 线程简介 83 4.1.1 什么是线程 83 4.1.2 为什么要使用多线程 84 4.1.3 线程优先级 85 4.1.4 线程的状态 87 4.1.5 Daemon线程 90 4.2 启动和终止线程 91 4.2.1 构造线程 91 4.2.2 启动线程 92 4.2.3 理解中断 92 4.2.4 过期的suspend()、resume()和stop() 93 4.2.5 安全地终止线程 95 4.3 线程间通信 96 4.3.1 volatile和synchronized关键字 96 4.3.2 等待/通知机制 98 4.3.3 等待/通知的经典范式 101 4.3.4 管道输入/输出流 102 4.3.5 Thread.join()的使用 103 4.3.6 ThreadLocal的使用 105 4.4 线程应用实例 106 4.4.1 等待超时模式 106 4.4.2 一个简单的数据库连接池示例 106 4.4.3 线程池技术及其示例 110 4.4.4 一个基于线程池技术的简单Web服务器 114 4.5 本章小结 118 第5章 Java中的锁 119 5.1 Lock接口 119 5.2 队列同步器 121 5.2.1 队列同步器的接口与示例 121 5.2.2 队列同步器的实现分析 124 5.3 重入锁 136 5.4 读写锁 140 5.4.1 读写锁的接口与示例 141 5.4.2 读写锁的实现分析 142 5.5 LockSupport工具 146 5.6 Condition接口 147 5.6.1 Condition接口与示例 148 5.6.2 Condition的实现分析 150 5.7 本章小结 154 第6章 Java并发容器和框架 155 6.1 ConcurrentHashMap的实现原理与使用 155 6.1.1 为什么要使用ConcurrentHashMap 155 6.1.2 ConcurrentHashMap的结构 156 6.1.3 ConcurrentHashMap的初始化 157 6.1.4 定位Segment 159 6.1.5 ConcurrentHashMap的操作 160 6.2 ConcurrentLinkedQueue 161 6.2.1 ConcurrentLinkedQueue的结构 162 6.2.2 入队列 162 6.2.3 出队列 165 6.3 Java中的阻塞队列 167 6.3.1 什么是阻塞队列 167 6.3.2 Java里的阻塞队列 168 6.3.3 阻塞队列的实现原理 172 6.4 Fork/Join框架 175 6.4.1 什么是Fork/Join框架 175 6.4.2 工作窃取算法 176 6.4.3 Fork/Join框架的设计 177 6.4.4 使用Fork/Join框架 177 6.4.5 Fork/Join框架的异常处理 179 6.4.6 Fork/Join框架的实现原理 179 6.5 本章小结 181 第7章 Java中的13个原子操作类 182 7.1 原子更新基本类型类 182 7.2 原子更新数组 184 7.3 原子更新引用类型 185 7.4 原子更新字段类 187 7.5 本章小结 188 第8章 Java中的并发工具类 189 8.1 等待多线程完成的CountDownLatch 189 8.2 同步屏障CyclicBarrier 191 8.2.1 CyclicBarrier简介 191 8.2.2 CyclicBarrier的应用场景 193 8.2.3 CyclicBarrier和CountDownLatch的区别 195 8.3 控制并发线程数的Semaphore 196 8.4 线程间交换数据的Exchanger 198 8.5 本章小结 199 第9章 Java中的线程池 200 9.1 线程池的实现原理 200 9.2 线程池的使用 203 9.2.1 线程池的创建 203 9.2.2 向线程池提交任务 205 9.2.3 关闭线程池 205 9.2.4 合理地配置线程池 206 9.2.5 线程池的监控 206 9.3 本章小结 207 第10章 Executor框架 208 10.1 Executor框架简介 208 10.1.1 Executor框架的两级调度模型 208 10.1.2 Executor框架的结构与成员 208 10.2 ThreadPoolExecutor详解 213 10.2.1 FixedThreadPool详解 213 10.2.2 SingleThreadExecutor详解 214 10.2.3 CachedThreadPool详解 215 10.3 ScheduledThreadPoolExecutor详解 217 10.3.1 ScheduledThreadPoolExecutor的运行机制 217 10.3.2 ScheduledThreadPoolExecutor的实现 218 10.4 FutureTask详解 221 10.4.1 FutureTask简介 222 10.4.2 FutureTask的使用 222 10.4.3 FutureTask的实现 224 10.5 本章小结 227 第11章 Java并发编程实践 228 11.1 生产者和消费者模式 228 11.1.1 生产者消费者模式实战 229 11.1.2 多生产者和多消费者场景 231 11.1.3 线程池与生产消费者模式 234 11.2 线上问题定位 234 11.3 性能测试 236 11.4 异步任务池 238 11.5 本章小结 240 ---------------------------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.3.1 安全性问题5 1.3.2 活跃性问题7 1.3.3 性能问题7 1.4 线程无处不在7 第一部分 基础知识 第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 迭代器与Concurrent-ModificationException68 5.1.3 隐藏迭代器69 5.2 并发容器70 5.2.1 ConcurrentHashMap71 5.2.2 额外的原子Map操作72 5.2.3 CopyOnWriteArrayList72 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 FutureTask80 5.5.3 信号量82 5.5.4 栅栏83 5.6 构建高效且可伸缩的结果缓存85 第二部分 结构化并发应用程序 第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与Future103 6.3.3 示例:使用Future实现页面渲染器104 6.3.4 在异构任务并行化中存在的局限106 6.3.5 CompletionService:Executor与BlockingQueue106 6.3.6 示例:使用CompletionService实现页面渲染器107 6.3.7 为任务设置时限108 6.3.8 示例:旅行预定门户网站109 第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 关闭ExecutorService127 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 第8章 线程池的使用138 8.1 在任务与执行策略之间的隐性耦合138 8.1.1 线程饥饿死锁139 8.1.2 运行时间较长的任务140 8.2 设置线程池的大小140 8.3 配置ThreadPoolExecutor141 8.3.1 线程的创建与销毁142 8.3.2 管理队列任务142 8.3.3 饱和策略144 8.3.4 线程工厂146 8.3.5 在调用构造函数后再定制ThreadPoolExecutor147 8.4 扩展 ThreadPoolExecutor148 8.5 递归算法的并行化149 第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 SwingWorker165 9.4 共享数据模型165 9.4.1 线程安全的数据模型166 9.4.2 分解数据模型166 9.5 其他形式的单线程子系统167 第三部分 活跃性、性能与测试 第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 第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 第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 第四部分 高级主题 第13章 显式锁227 13.1 Lock与 ReentrantLock227 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 第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 AbstractQueuedSynchronizer254 14.6 java.util.concurrent同步器类中的 AQS257 14.6.1 ReentrantLock257 14.6.2 Semaphore与CountDownLatch258 14.6.3 FutureTask259 14.6.4 ReentrantReadWriteLock259 第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 第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 附录A 并发性标注289 参考文献291 |