书籍详情

Java高并发核心编程 卷2:多线程、锁、JMM、JUC、高并发设计模式(加强版)

Java高并发核心编程 卷2:多线程、锁、JMM、JUC、高并发设计模式(加强版)

作者:尼恩

出版社:清华大学出版社

出版时间:2022-11-01

ISBN:9787302620983

定价:¥118.00

购买这本书可以去
内容简介
  本书聚焦Java高并发编程基础知识,介绍Java多线程、线程池、内置锁、JMM、CAS、JUC、高并发设计模式等并发编程方面的核心原理和实战知识。本书共10章。第1、2章剖析多线程、线程池的核心原理和实战应用,揭秘线程安全问题和Java内置锁的核心原理。第3、4章讲解CAS原理与JUC原子类、JMM的核心原理,揭秘CAS操作的弊端和两类规避措施,以及Java内存可见性和volatile关键字的底层知识。第5章讲解JUC显式锁的原理和各种显式锁的使用。第6章阐述JUC高并发的基础设施——AQS抽象同步器的核心原理。第7章介绍JUC容器类。第8~10章介绍常见的Java高并发设计模式的原理和使用。本书既可以作为Java工程师、架构师的编程参考书,又可以作为参加互联网大厂面试、笔试的人员的学习参考书。
作者简介
  尼恩中南大学硕士,资深系统架构师、IT领域资深作家、著名博主、从业十余年,先后在华为、神州数码等公司从事技术研发、架构工作。长期专注于高性能Web平台、高性能通信、高性能搜索、数据挖掘等领域的3高架构研究、架构实操、核心代码开发工作,以及核心中间件、底层源码研究工作,负责过多个亿级RMB智慧城市平台、大型政务平台、数据中台架构、技术中台架构工作,发起的3高研究社群“疯狂创客圈”目前有研究人员1100多人。唐欢计算机专业硕士,资深系统架构师、资深博主,拥有多年Java开发和系统架构经验,多年敏捷开发的项目管理经验,现在国内科技企业担任系统架构师一职,主持企业软件的系统架构和产品研发工作。孙精科南京理工大学计算机专业硕士,上海交通大学EMBA。行业内知名信息化系统专家,具有丰富的大型信息系统的研发及管理经验。近10年来,主持上市公司信息系统建设、三维开发、通信协议转换、数据采集、软硬件一体化产品的研发。具有丰富的国际国内项目咨询经验,担任多项省级项目负责人,主持的多个项目获得省部级奖项;2003—2008年,在东南亚、中东、非洲、南美等地执行国际咨询项目。朱达华资深技术总监、美国协会PMI项目管理师、敏捷教练。近10年来在一线主持技术管理工作,擅长系统架构分析和设计,负责过多个大型省市级系统建设,服务数千万的用户。
目录

第1章  多线程原理与实战 1
1.1  两个技术面试故事 1
1.2  无处不在的进程和线程 2
1.2.1  进程的基本原理 3
1.2.2  线程的基本原理 4
1.2.3  进程与线程的区别 7
1.3  创建线程的4种方法 7
1.3.1  Thread类详解 8
1.3.2  创建一个空线程 10
1.3.3  线程创建方法一:继承Thread类创建线程类 11
1.3.4  线程创建方法二:实现Runnable接口创建线程目标类 12
1.3.5  优雅创建Runnable线程目标类的两种方式 14
1.3.6  实现Runnable接口的方式创建线程目标类的优缺点 16
1.3.7  线程创建方法三:使用Callable和FutureTask创建线程 20
1.3.8  线程创建方法四:通过线程池创建线程 25
1.4  线程的核心原理 28
1.4.1  线程的调度与时间片 28
1.4.2  线程的优先级 29
1.4.3  线程的生命周期 31
1.4.4  一个线程状态的简单演示案例 33
1.4.5  使用Jstack工具查看线程状态 35
1.5  线程的基本操作 36
1.5.1  线程名称的设置和获取 36
1.5.2  线程的sleep操作 38
1.5.3  线程的interrupt操作 39
1.5.4  线程的join操作 42
1.5.5  线程的yield操作 46
1.5.6  线程的daemon操作 48
1.5.7  线程状态总结 52
1.6  线程池原理与实战 54
1.6.1  JUC的线程池架构 54
1.6.2  Executors的4种快捷创建线程池的方法 56
1.6.3  线程池的标准创建方式 62
1.6.4  向线程池提交任务的两种方式 63
1.6.5  线程池的任务调度流程 66
1.6.6  ThreadFactory(线程工厂) 68
1.6.7  任务阻塞队列 70
1.6.8  调度器的钩子方法 70
1.6.9  线程池的拒绝策略 72
1.6.10  线程池的优雅关闭 75
1.6.11  Executors快捷创建线程池的潜在问题 80
1.7  确定线程池的线程数 83
1.7.1  按照任务类型对线程池进行分类 83
1.7.2  为IO密集型任务确定线程数 84
1.7.3  为CPU密集型任务确定线程数 86
1.7.4  为混合型任务确定线程数 87
1.8  ThreadLocal原理与实战 89
1.8.1  ThreadLocal的基本使用 89
1.8.2  ThreadLocal使用场景 91
1.8.3  使用ThreadLocal进行线程隔离 92
1.8.4  使用ThreadLocal进行跨函数数据传递 93
1.8.5  ThreadLocal内部结构演进 94
1.8.6  ThreadLocal源码分析 96
1.8.7  ThreadLocalMap源码分析 99
1.8.8  ThreadLocal综合使用案例 102
第2章  Java内置锁的核心原理 106
2.1  线程安全问题 106
2.1.1  自增运算不是线程安全的 106
2.1.2  临界区资源与临界区代码段 108
2.2  synchronized关键字 109
2.2.1  synchronized同步方法 110
2.2.2  synchronized同步块 110
2.2.3  静态的同步方法 112
2.3  生产者-消费者问题 113
2.3.1  生产者-消费者模式 113
2.3.2  一个线程不安全的实现版本 114
2.3.3  一个线程安全的实现版本 120
2.4  Java对象结构与内置锁 121
2.4.1  Java对象结构 121
2.4.2  Mark Word的结构信息 124
2.4.3  使用JOL工具查看对象的布局 126
2.4.4  大小端问题 129
2.4.5  无锁、偏向锁、轻量级锁和重量级锁 131
2.5  偏向锁的原理与实战 132
2.5.1  偏向锁的核心原理 132
2.5.2  偏向锁的演示案例 133
2.5.3  偏向锁的膨胀和撤销 136
2.5.4  全局安全点原理和偏向锁撤销的性能问题 137
2.6  轻量级锁的原理与实战 139
2.6.1  轻量级锁的核心原理 139
2.6.2  轻量级锁的案例演示 141
2.6.3  轻量级锁的分类 143
2.6.4  轻量级锁的膨胀 144
2.7  重量级锁的原理与实战 144
2.7.1  重量级锁的核心原理 144
2.7.2  重量级锁的开销 146
2.7.3  重量级锁的演示案例 147
2.8  偏向锁、轻量级锁与重量级锁的对比 149
2.9  线程间通信 150
2.9.1  线程间通信定义 150
2.9.2  低效的线程轮询 150
2.9.3  wait方法、notify方法的原理 152
2.9.4  “等待-通知”通信模式演示案例 154
2.9.5  生产者-消费者之间的线程间通信 156
2.9.6  需要在synchronized同步块的内部使用wait和notify 158
第3章  CAS原理与JUC原子类 160
3.1  什么是CAS 160
3.1.1  Unsafe类中的CAS方法 160
3.1.2  使用CAS进行无锁编程 162
3.1.3  使用无锁编程实现轻量级安全自增 164
3.1.4  字段偏移量的计算 165
3.2  JUC原子类 167
3.2.1  JUC中的Atomic原子操作包 167
3.2.2  基础原子类AtomicInteger 168
3.2.3  数组原子类AtomicIntegerArray 170
3.2.4  AtomicInteger线程安全原理 171
3.3  对象操作的原子性 173
3.3.1  引用类型原子类 173
3.3.2  属性更新原子类 174
3.4  ABA问题 175
3.4.1  了解ABA问题 175
3.4.2  ABA问题解决方案 177
3.4.3  使用AtomicStampedReference解决ABA问题 177
3.4.4  使用AtomicMarkableReference解决ABA问题 179
3.5  提升高并发场景下CAS操作的性能 180
3.5.1  以空间换时间:LongAdder 181
3.5.2  LongAdder的原理 183
3.6  CAS在JDK中的广泛应用 189
3.6.1  CAS操作的弊端和规避措施 190
3.6.2  CAS操作在JDK中的应用 191
第4章  可见性与有序性原理 192
4.1  CPU物理缓存结构 192
4.2  并发编程的三大问题 194
4.2.1  原子性问题 194
4.2.2  可见性问题 195
4.2.3  有序性问题 196
4.3  硬件层的MESI协议原理 198
4.3.1  总线锁和缓存锁 199
4.3.2  MSI协议 201
4.3.3  MESI协议及RFO请求 201
4.3.4  Store Buffer和Invalidate Queue 206
4.3.5  volatile的原理 207
4.4  有序性与内存屏障 209
4.4.1  重排序 210
4.4.2  As-if-Serial规则 211
4.4.3  硬件层面的内存屏障 212
4.5  JMM详解 214
4.5.1  什么是Java内存模型 214
4.5.2  JMM与JMM物理内存的区别 216
4.5.3  JMM的8个操作 218
4.5.4  JMM如何解决有序性问题 219
4.6  Happens-Before规则 222
4.6.1  Happens-Before规则介绍 222
4.6.2  规则1:顺序性规则 223
4.6.3  规则2:volatile规则 223
4.6.4  规则3:传递性规则 225
4.6.5  规则4:监视锁规则 226
4.6.6  规则5:start()规则 227
4.6.7  规则6:join()规则 227
4.7  volatile语义中的内存屏障 228
4.7.1  volatile写操作的内存屏障 229
4.7.2  volatile读操作的内存屏障 229
4.7.3  对volatile变量的写入进行性能优化 230
4.8  volatile不具备原子性 232
4.8.1  volatile变量的自增实例 232
4.8.2  volatile变量的复合操作不具备原子性的原理 233
第5章  JUC显式锁的原理与实战 235
5.1  显式锁 235
5.1.1  显式锁Lock接口 236
5.1.2  可重入锁ReentrantLock 237
5.1.3  使用显式锁的模板代码 239
5.1.4  基于显式锁进行“等待-通知”方式的线程间通信 241
5.1.5  LockSupport 244
5.1.6  显式锁的分类 247
5.2  悲观锁和乐观锁 249
5.2.1  悲观锁存在的问题 249
5.2.2  通过CAS实现乐观锁 249
5.2.3  不可重入的自旋锁 250
5.2.4  可重入的自旋锁 251
5.2.5  CAS可能导致“总线风暴” 252
5.2.6  CLH自旋锁 254
5.3  公平锁与非公平锁 261
5.3.1  非公平锁实战 261
5.3.2  公平锁实战 262
5.4  可中断锁与不可中断锁 263
5.4.1  锁的可中断抢占 263
5.4.2  死锁的监测与中断 265
5.5  独占锁与共享锁 268
5.5.1  独占锁 268
5.5.2  共享锁Semaphore 268
5.5.3  共享锁CountDownLatch 271
5.6  读写锁 273
5.6.1  读写锁ReentrantReadWriteLock 273
5.6.2  锁的升级与降级 275
5.6.3  StampedLock 276
第6章  AQS抽象同步器核心原理 280
6.1  锁与队列的关系 280
6.2  AQS的核心成员 282
6.2.1  状态标志位 282
6.2.2  队列节点类 283
6.2.3  FIFO双向同步队列 284
6.2.4  JUC显式锁与AQS的关系 285
6.2.5  ReentrantLock与AQS的组合关系 285
6.3  AQS中的模板模式 287
6.3.1  模板模式 288
6.3.2  一个模板模式的参考实现 289
6.3.3  AQS的模板流程 291
6.3.4  AQS中的钩子方法 291
6.4  通过AQS实现一把简单的独占锁 292
6.4.1  简单的独占锁的UML类图 293
6.4.2  简单的独占锁的实现 293
6.4.3  SimpleMockLock测试用例 295
6.5  AQS锁抢占的原理 296
6.5.1  显式锁抢占的总体流程 296
6.5.2  AQS模板方法:acquire(arg) 297
6.5.3  钩子实现:tryAcquire(arg) 297
6.5.4  直接入队:addWaiter 297
6.5.5  自旋入队:enq 298
6.5.6  自旋抢占:acquireQueued() 299
6.5.7  挂起预判:shouldParkAfterFailedAcquire 300
6.5.8  线程挂起:parkAndCheckInterrupt() 302
6.6  AQS两个关键点:节点的入队和出队 302
6.6.1  节点的自旋入队 303
6.6.2  节点的出队 303
6.7  AQS锁释放的原理 304
6.7.1  SimpleMockLock独占锁的释放流程 304
6.7.2  AQS模板方法:release() 305
6.7.3  钩子实现:tryRelease() 305
6.7.4  唤醒后驱:unparkSuccessor() 306
6.8  ReentrantLock的抢锁流程 306
6.8.1  ReentrantLock非公平锁的抢占流程 307
6.8.2  非公平锁的同步器子类 307
6.8.3  非公平抢占的钩子方法:tryAcquire(arg) 308
6.8.4  ReentrantLock公平锁的抢占流程 308
6.8.5  公平锁的同步器子类 309
6.8.6  公平抢占的钩子方法:tryAcquire(arg) 309
6.8.7  是否有后驱节点的判断 310
6.9  AQS条件队列 310
6.9.1  Condition基本原理 310
6.9.2  await()等待方法原理 312
6.9.3  signal()唤醒方法原理 313
6.9.4  节点入队的时机 314
6.10  AQS的实际应用 315
第7章  JUC容器类 316
7.1  线程安全的同步容器类 316
7.2  JUC高并发容器 318
7.3  CopyOnWriteArrayList 319
7.3.1  CopyOnWriteArrayList的使用 320
7.3.2  CopyOnWriteArrayList原理 321
7.3.3  CopyOnWriteArrayList读取操作 322
7.3.4  CopyOnWriteArrayList写入操作 323
7.3.5  CopyOnWriteArrayList的迭代器实现 323
7.4  BlockingQueue 324
7.4.1  BlockingQueue的特点 324
7.4.2  阻塞队列的常用方法 325
7.4.3  常见的BlockingQueue 326
7.4.4  ArrayBlockingQueue的基本使用 328
7.4.5  ArrayBlockingQueue构造器和成员 330
7.4.6  非阻塞式添加元素:add()、offer()方法的原理 332
7.4.7  阻塞式添加元素:put()方法的原理 333
7.4.8  非阻塞式删除元素:poll()方法的原理 335
7.4.9  阻塞式删除元素:take()方法的原理 335
7.4.10  peek()直接返回当前队列的队首元素 337
7.5  ConcurrentHashMap 337
7.5.1  HashMap和HashTable的问题 337
7.5.2  JDK 1.7版本ConcurrentHashMap的结构 338
7.5.3  JDK 1.7版本ConcurrentHashMap的核心原理 339
7.5.4  JDK 1.8版本ConcurrentHashMap的结构 346
7.5.5  JDK 1.8版本ConcurrentHashMap的核心原理 347
7.5.6  JDK 1.8版本ConcurrentHashMap的核心源码 350
第8章  高并发设计模式 353
8.1  线程安全的单例模式 353
8.1.1  从饿汉式单例到懒汉式单例 353
8.1.2  使用内置锁保护懒汉式单例 354
8.1.3  双重检查锁方式 355
8.1.4  使用双重检查锁 volatile 356
8.1.5  使用静态内部类实例懒汉单例模式 357
8.2  Master-Worker模式 357
8.2.1  Master-Worker模式的参考实现 358
8.2.2  Netty中的Master-Worker模式的实现 362
8.2.3  Nginx中的Master-Worker模式的实现 363
8.3  ForkJoin模式 364
8.3.1  ForkJoin模式的原理 364
8.3.2  ForkJoin框架 365
8.3.3  ForkJoin框架使用实战 366
8.3.4  ForkJoin框架的核心API 367
8.3.5  工作窃取算法 370
8.3.6  ForkJoin框架的原理 371
8.4  生产者-消费者模式 372
8.5  Future模式 373
第9章  异步回调模式 375
9.1  从泡茶的案例说起 375
9.2  join:异步阻塞之闷葫芦 376
9.2.1  线程的合并流程 376
9.2.2  调用join()实现异步泡茶喝 376
9.2.3  join()方法详解 377
9.3  FutureTask:异步调用之重武器 378
9.3.1  通过FutureTask获取异步执行结果的步骤 379
9.3.2  使用FutureTask实现异步泡茶喝 379
9.4  异步回调与异步阻塞调用 382
9.5  Guava的异步回调模式 383
9.5.1  详解FutureCallback 383
9.5.2  详解ListenableFuture 384
9.5.3  ListenableFuture异步任务 384
9.5.4  使用Guava实现泡茶喝的实例 385
9.5.5  Guava异步回调和Java异步调用的区别 388
9.6  Netty的异步回调模式 389
9.6.1  GenericFutureListener接口详解 389
9.6.2  Netty的Future接口详解 389
9.6.3  ChannelFuture的使用 390
9.6.4  Netty的出站和入站异步回调 390
9.7  异步回调模式小结 391
第10章  CompletableFuture异步回调 392
10.1  CompletableFuture详解 392
10.1.1  CompletableFuture的UML类关系 392
10.1.2  CompletionStage接口 393
10.1.3  使用runAsync和supplyAsync创建子任务 393
10.1.4  设置的子任务回调钩子 394
10.1.5  调用handle()方法统一处理异常和结果 396
10.1.6  线程池的使用 397
10.2  异步任务的串行执行 398
10.2.1  thenApply()方法 398
10.2.2  thenRun()方法 399
10.2.3  thenAccept()方法 399
10.2.4  thenCompose()方法 400
10.2.5  4个任务串行方法的区别 401
10.3  异步任务的合并执行 402
10.3.1  thenCombine()方法 402
10.3.2  runAfterBoth()方法 404
10.3.3  thenAcceptBoth()方法 404
10.3.4  allOf()等待所有的任务结束 405
10.4  异步任务的选择执行 405
10.4.1  applyToEither()方法 406
10.4.2  runAfterEither()方法 407
10.4.3  acceptEither()方法 407
10.5  CompletableFuture的综合案例 408
10.5.1  使用CompletableFuture实现泡茶喝实例 408
10.5.2  使用CompletableFuture进行多个RPC调用 410
10.5.3  使用RxJava模拟RPC异步回调 411
 
猜您喜欢

读书导航