本书从实际需求出发,全面细致地介绍了高并发编程的基础知识、核心原理、实战案例和系统架构等内容。通过阅读和学习本书,读者可以对高并发编程有更加全面、深入、透彻的理解,提高对高并发编程问题的处理能力和项目实战能力,并站在更高的层面解决高并发编程系统架构问题。
第1篇 基础知识
第1章 操作系统线程调度 2
1.1 冯·诺依曼体系结构 2
1.1.1 概述 2
1.1.2 计算机五大组成部分 3
1.2 CPU架构 5
1.2.1 CPU的组成部分 5
1.2.2 CPU逻辑结构 6
1.2.3 单核CPU的不足 8
1.2.4 多核CPU架构 8
1.2.5 多CPU架构 10
1.3 操作系统线程 11
1.3.1 用户级线程 11
1.3.2 内核级线程 12
1.3.3 混合级线程 14
1.4 Java线程与操作系统线程的关系 15
1.5 本章总结 16
第2章 并发编程概述 17
2.1 并发编程的基本概念 17
2.1.1 程序 17
2.1.2 进程与线程 17
2.1.3 线程组 18
2.1.4 用户线程与守护线程 19
2.1.5 并行与并发 20
2.1.6 同步与异步 21
2.1.7 共享与独享 21
2.1.8 临界区 22
2.1.9 阻塞和非阻塞 22
2.2 并发编程的风险 22
2.2.1 安全性问题 22
2.2.2 活跃性问题 23
2.2.3 性能问题 24
2.3 并发编程中的锁 24
2.3.1 悲观锁与乐观锁 24
2.3.2 公平锁与非公平锁 25
2.3.3 独占锁与共享锁 26
2.3.4 可重入锁与不可重入锁 26
2.3.5 可中断锁与不可中断锁 26
2.3.6 读/写锁 27
2.3.7 自旋锁 27
2.3.8 死锁、饥饿与活锁 27
2.4 本章总结 28
第2篇 核心原理
第3章 并发编程的三大核心问题 30
3.1 分工问题 30
3.1.1 类比现实案例 30
3.1.2 并发编程中的分工 32
3.2 同步问题 32
3.2.1 类比现实案例 33
3.2.2 并发编程中的同步 33
3.3 互斥问题 35
3.3.1 类比现实案例 35
3.3.2 并发编程中的互斥 35
3.4 本章总结 36
第4章 并发编程的本质问题 37
4.1 计算机的核心矛盾 37
4.1.1 核心矛盾概述 37
4.1.2 CPU如何解决核心矛盾 38
4.1.3 操作系统如何解决核心矛盾 38
4.1.4 编译程序如何解决核心矛盾 38
4.1.5 引发的问题 39
4.2 原子性 39
4.2.1 原子性概述 39
4.2.2 原子性问题 41
4.2.3 Java中的原子性问题 42
4.2.4 原子性问题总结 46
4.3 可见性 46
4.3.1 可见性概述 46
4.3.2 可见性问题 47
4.3.3 Java中的可见性问题 49
4.3.4 可见性问题总结 51
4.4 有序性 51
4.4.1 有序性概述 51
4.4.2 有序性问题 52
4.4.3 Java中的有序性问题 53
4.4.4 有序性问题总结 56
4.5 解决方案 57
4.5.1 原子性问题解决方案 57
4.5.2 可见性与有序性问题解决方案 57
4.6 本章总结 58
第5章 原子性的核心原理 59
5.1 原子性原理 59
5.2 处理器保证原子性 60
5.2.1 CPU保证基本内存操作的原子性 60
5.2.2 总线锁保证原子性 60
5.2.3 缓存锁保证原子性 62
5.3 互斥锁保证原子性 62
5.3.1 互斥锁模型 62
5.3.2 优化后的互斥锁模型 63
5.4 CAS保证原子性 64
5.5 本章总结 64
第6章 可见性与有序性核心原理 65
6.1 CPU多级缓存架构 65
6.1.1 CPU为何使用多级缓存架构 65
6.1.2 CPU多级缓存架构原理 66
6.1.3 CPU的计算流程 67
6.2 缓存一致性 68
6.2.1 什么是缓存一致性 68
6.2.2 缓存一致性协议 69
6.2.3 MESI协议缓存状态 70
6.2.4 MESI协议的状态转换 70
6.2.5 MESI协议带来的问题 76
6.3 伪共享 76
6.3.1 伪共享的概念 76
6.3.2 伪共享产生的场景 77
6.3.3 如何解决伪共享问题 77
6.4 volatile核心原理 78
6.4.1 保证可见性核心原理 78
6.4.2 保证有序性核心原理 79
6.4.3 volatile的局限性 81
6.5 内存屏障 82
6.5.1 编译器重排序 82
6.5.2 CPU重排序 83
6.5.3 as-if-serial原则 83
6.5.4 计算机硬件实现的内存屏障 84
6.6 Java内存模型 84
6.6.1 Java内存模型的概念 85
6.6.2 Java内存模型的八大操作 85
6.6.3 Java内存模型解决可见性与有序性问题 87
6.7 Happens-Before原则 90
6.7.1 Happens-Before原则概述 90
6.7.2 程序次序原则 90
6.7.3 volatile变量原则 91
6.7.4 传递原则 91
6.7.5 锁定原则 91
6.7.6 线程启动原则 92
6.7.7 线程终结原则 93
6.7.8 线程中断原则 93
6.7.9 对象终结原则 94
6.8 本章总结 95
第7章 synchronized核心原理 96
7.1 synchronized用法 96
7.1.1 同步实例方法 97
7.1.2 同步静态方法 98
7.1.3 同步代码块 99
7.2 Java对象结构 102
7.2.1 对象结构总览 102
7.2.2 对象头 103
7.2.3 实例数据 103
7.2.4 对齐填充 103
7.3 Java对象头 104
7.3.1 Mark Word 104
7.3.2 类型指针 106
7.3.3 数组长度 106
7.4 使用JOL查看对象信息 107
7.4.1 引入JOL环境依赖 107
7.4.2 打印对象信息 107
7.4.3 打印对象锁状态 109
7.5 synchronized核心原理 115
7.5.1 synchronized底层原理 115
7.5.2 Monitor锁原理 116
7.5.3 反编译synchronized方法 118
7.5.4 反编译synchronized代码块 119
7.6 偏向锁 121
7.6.1 偏向锁核心原理 122
7.6.2 偏向锁的撤销 122
7.6.3 偏向锁案例 123
7.7 轻量级锁 124
7.7.1 轻量级锁核心原理 124
7.7.2 轻量级锁案例 126
7.8 重量级锁 127
7.8.1 重量级锁核心原理 127
7.8.2 重量级锁案例 127
7.9 锁升级的过程 129
7.10 锁消除 130
7.11 本章总结 131
第8章 AQS核心原理 132
8.1 AQS核心数据结构 132
8.1.1 AQS数据结构原理 132
8.1.2 AQS内部队列模式 133
8.2 AQS底层锁的支持 134
8.2.1 核心状态位 134
8.2.2 核心节点类 135
8.2.3 独占锁模式 137
8.2.4 共享锁模式 142
8.3 本章总结 145
第9章 Lock锁核心原理 146
9.1 显示锁原理 146
9.2 公平锁与非公平锁原理 148
9.2.1 公平锁原理 148
9.2.2 ReentrantLock中的公平锁 149
9.2.3 公平锁实战 153
9.2.4 非公平锁原理 154
9.2.5 ReentrantLock中的非公平锁 156
9.2.6 非公平锁实战 159
9.3 悲观锁与乐观锁原理 159
9.3.1 悲观锁原理 160
9.3.2 悲观锁实战 160
9.3.3 乐观锁原理 162
9.3.4 乐观锁实战 162
9.4 可中断锁与不可中断锁原理 163
9.4.1 可中断锁原理 163
9.4.2 可中断锁实战 164
9.4.3 不可中断锁原理 166
9.4.4 不可中断锁实战 166
9.5 排他锁与共享锁原理 167
9.5.1 排他锁原理 167
9.5.2 排他锁实战 167
9.5.3 共享锁原理 169
9.5.4 共享锁实战 169
9.6 可重入锁原理 170
9.6.1 可重入锁原理 170
9.6.2 可重入锁实战 172
9.7 读/写锁原理 175
9.7.1 读/写锁原理 175
9.7.2 ReadWriteLock读/写锁 176
9.7.3 ReadWriteLock锁降级 177
9.7.4 StampedLock读/写锁 178
9.7.5 StampedLock锁的升级与降级 179
9.7.6 读/写锁实战 182
9.8 LockSupport原理 185
9.8.1 LockSupport原理 185
9.8.2 LockSupport实战 185
9.9 本章总结 187
第10章 CAS核心原理 188
10.1 CAS的基本概念 188
10.2 CAS的核心类Unsafe 189
10.2.1 Unsafe类的核心方法 190
10.2.2 Unsafe类实战 192
10.3 使用CAS实现count++ 194
10.3.1 案例分析 194
10.3.2 程序实现 194
10.3.3 测试程序 198
10.4 ABA问题 199
10.4.1 ABA问题概述 199
10.4.2 ABA问题解决方案 200
10.4.3 Java如何解决ABA问题 200
10.5 本章总结 202
第11章 死锁的核心原理 203
11.1 死锁的基本概念 203
11.2 死锁的分析 204
11.2.1 线程不安全 204
11.2.2 串行执行 206
11.2.3 发生死锁 208
11.3 形成死锁的必要条件 210
11.4 死锁的预防 210
11.5 本章总结 216
第12章 锁优化 217
12.1 缩小锁的范围 217
12.2 减小锁的粒度 219
12.3 锁分离 220
12.4 锁分段 221
12.5 锁粗化 221
12.6 避免热点区域问题 222
12.7 独占锁的替换方案 223
12.8 其他优化方案 223
12.9 本章总结 223
第13章 线程池核心原理 224
13.1 线程池的核心状态 224
13.1.1 核心状态说明 224
13.1.2 核心状态的流转过程 225
13.2 线程池的创建方式 227
13.2.1 通过Executors类创建线程池 227
13.2.2 通过ThreadPoolExecutor类创建线程池 229
13.2.3 通过ForkJoinPool类创建线程池 232
13.2.4 通过ScheduledThreadPoolExecutor类创建线程池 234
13.3 线程池执行任务的核心流程 235
13.3.1 执行任务的流程 235
13.3.2 拒绝策略 237
13.4 线程池的关闭方式 238
13.4.1 shutdown()方法 238
13.4.2 shutdownNow()方法 238
13.5 如何确定最佳线程数 238
13.5.1 CPU密集型程序 238
13.5.2 I/O密集型程序 239
13.6 本章总结 239
第14章 ThreadLocal核心原理 240
14.1 ThreadLocal的基本概念 240
14.2 ThreadLocal的使用案例 241
14.3 ThreadLocal的核心原理 244
14.3.1 Thread类源码 244
14.3.2 set()方法 244
14.3.3 get()方法 245
14.3.4 remove()方法 247
14.4 ThreadLocal变量的不继承性 247
14.5 InheritableThreadLocal的使用案例 249
14.6 InheritableThreadLocal的核心原理 250
14.7 本章总结 253
第3篇 实战案例
第15章 手动开发线程池实战 256
15.1 案例概述 256
15.2 项目搭建 257
15.3 核心类实现 257
15.3.1 定义核心字段 257
15.3.2 创建内部类WorkThread 258
15.3.3 创建线程池的构造方法 259
15.3.4 创建执行任务的方法 260
15.3.5 创建关闭线程池的方法 260
15.3.6 完整源代码示例 260
15.4 测试程序 262
15.5 本章总结 264
第16章 基于CAS实现自旋锁实战 265
16.1 案例概述 265
16.2 项目搭建 266
16.3 核心类实现 266
16.3.1 CasLock接口实现 266
16.3.2 MyCasLock类实现 267
16.4 测试程序 268
16.5 本章总结 270
第17章 基于读/写锁实现缓存实战 271
17.1 案例概述 271
17.2 项目搭建 272
17.3 核心类实现 272
17.3.1 ReadWriteCache<K, V>核心接口的实现 272
17.3.2 ConcurrentReadWriteCache<K, V>核心类的实现 273
17.4 测试程序 278
17.5 本章总结 279
第18章 基于AQS实现可重入锁实战 280
18.1 案例概述 280
18.2 项目搭建 281
18.3 核心类实现 281
18.3.1 AQSSync内部类的实现 281
18.3.2 ReentrantAQSLock核心类的实现 284
18.3.3 完整源代码 285
18.4 测试程序 287
18.5 本章总结 290
第4篇 系统架构
第19章 深度解密分布式锁架构 292
19.1 锁解决的本质问题 292
19.2 电商超卖问题 292
19.2.1 超卖问题概述 293
19.2.2 超卖问题案例 293
19.3 JVM提供的锁 295
19.3.1 JVM锁的原理 295
19.3.2 JVM锁的不足 295
19.4 分布式锁 297
19.4.1 分布式锁的实现方法 297
19.4.2 分布式锁的基本要求 298
19.5 CAP理论与分布式锁模型 298
19.5.1 CAP理论 298
19.5.2 基于Redis的AP架构模型 299
19.5.3 基于Zookeeper的CP架构模型 299
19.5.4 AP架构模型的问题与解决方案 300
19.6 基于Redis实现分布式锁 301
19.6.1 Redis命令分析 301
19.6.2 引入分布式锁 302
19.6.3 引入try-finally代码块 303
19.6.4 引入Redis超时机制 304
19.6.5 加锁操作原子化 305
19.6.6 误删锁分析 307
19.6.7 实现加锁和解锁归一化 308
19.6.8 可重入性分析 309
19.6.9 解决可重入性问题 311
19.6.10 实现锁的阻塞性 313
19.6.11 解决锁失效问题 315
19.6.12 解锁操作原子化 321
19.7 本章总结 322
第20章 深度解密秒杀系统架构 323
20.1 电商系统架构 323
20.2 秒杀系统的特点 326
20.2.1 秒杀系统的业务特点 326
20.2.2 秒杀系统的技术特点 327
20.3 秒杀系统的方案 328
20.3.1 秒杀系统的三个阶段 328
20.3.2 秒杀系统的性能优化 329
20.4 秒杀系统设计 330
20.4.1 同步下单流程 330
20.4.2 异步下单流程 332
20.5 扣减库存设计 336
20.5.1 下单减库存 336
20.5.2 付款减库存 337
20.5.3 预扣减库存 337
20.5.4 扣减库存问题的解决方案 337
20.5.5 秒杀系统扣减库存方案 338
20.6 Redis助力秒杀系统 338
20.6.1 Redis实现扣减库存 338
20.6.2 完美解决超卖问题 340
20.6.3 Redis分割库存 341
20.6.4 缓存穿透技术 342
20.7 服务器性能优化 343
20.7.1 操作系统参数 343
20.7.2 优化套接字缓冲区 344
20.7.3 优化频繁接收大文件 345
20.7.4 优化TCP连接 346
20.8 本章总结 347