首页>参考读物>计算机科学与技术>软件与程序设计

Java高并发核心编程 卷2:多线程、锁、JMM、JUC、高并发设计模式
作者 : 尼恩 编著
出版日期 : 2021-04-21
ISBN : 978-7-111-67988-2
定价 : 129.00元
扩展资源下载
扩展信息
语种 : 简体中文
页数 : 484
开本 : 16
原书名 :
原出版社:
属性分类: 店面
包含CD : 无CD
绝版 : 未绝版
图书简介

本书聚焦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高并发知识讲解得浅显易懂

图书前言

  移动时代、5G时代、物联网时代的大幕已经开启,新时代提升了对Java应用的高性能、高并发的要求,也抬升了Java工程师的技术台阶和面试门槛。
  很多公司的面试题从某个侧面反映了生产场景的技术要求。之前只有BAT等大公司才有高并发技术相关的面试题,现在与Java项目相关的整个行业基本都涉及此类面试题。多线程、线程池、内置锁、JMM、CAS、JUC、高并发设计模式等Java并发编程方面的面试题,从以前的加分题变成现在的基础题。本书着重介绍Java并发编程基础知识,揭秘Java高并发编程的核心难题和解决方案。
本书内容
  本书是三卷本《Java高并发核心编程》的第2卷,旨在帮助大家掌握Java高并发基础知识:多线程、线程池、内置锁、JMM、CAS、JUC、高并发设计模式、Java异步回调、CompletableFuture类等。
  第1章介绍线程的核心原理、线程的基本操作、线程池的核心原理、JUC的线程池架构、 4种快捷创建线程池的方法。除此之外,还从生产实际的角度出发,介绍在生产场景中如何合理预估3类线程池(IO密集型、CPU密集性、混合型)的线程数。
  第2章基于生产者-消费者模式的实战案例介绍线程安全问题和Java内置锁的核心原理。首先揭秘Java对象的存储布局、对象头的具体结构,并介绍如何用JOL工具查看对象的结构。然后介绍synchronized内置锁的核心原理,以及内置锁从偏向锁到轻量级锁再到重量级锁的升级 过程。
  第3章介绍CAS原理与JUC原子类,并解密在争用激烈的高并发场景下,如何提升高CAS操作的性能。最后揭秘CAS操作的弊端和两类规避措施。
  第4章介绍Java并发编程的三大问题——原子性问题、可见性问题和有序性问题,阐述JMM的核心原理,揭秘Java内存可见性和volatile关键字的底层知识。
  第5章介绍JUC显式锁的原理与实战。首先介绍使用显式锁的正确方法、显式锁的分类,然后揭秘CAS可能导致的“总线风暴”和CLH自旋锁,最后从实例出发介绍JUC中的可中断锁和不可中断锁、共享锁与独占锁、读写锁。
  第6章介绍JUC高并发的基础设施——AQS抽象同步器的核心原理。本章从模板模式入手,抽丝剥茧,层层深入,揭秘AQS的内部结构。然后结合SimpleMockLock独占锁的释放流程、ReentrantLock的抢锁流程,图文并茂地剖析释放、抢占AQS锁的源码和原理。
  第7章介绍JUC容器类,包括CopyOnWriteArrayList、BlockingQueue、ConcurrentHashMap等高并发容器类的原理和使用。
  第8章介绍高并发设计模式,主要包括Java开发必须掌握的安全单例模式、Master-Worker模式、ForkJoin模式、生产者-消费者模式、Future模式。
  第9章着重介绍高并发编程中经常用到的高并发设计模式——异步回调模式。
  第10章介绍Java 8所提供的一个具备异步回调能力的新工具类——CompletableFuture类的原理和使用。
  以上内容是开发Java高并发应用所必备的知识,也是广大Java工程师必须掌握的高并发基础知识。
读者对象
  (1)对Java编程感兴趣的大专院校学生。
  (2)Java工程师。
  (3)Java架构师。
本书源代码下载
  本书的源代码可以从https://gitee.com/crazymaker/Java-high-concurrency-core-Programming- Volume-2-source-code.git下载。另外,还可以登录机械工业出版社华章分社网站(www.hzbook.com)下载,方法是:先搜索到本书,然后在页面上的“资料下载”模块下载即可。如果下载有问题,请发送电子邮件至booksaga@126.com,邮件主题为“Java高并发编程 卷2下载资源”。
勘误和支持
  由于笔者水平和能力有限,书中不妥之处在所难免,希望读者批评指正。本系列书的读者QQ群为104131248,目前群中已经包含了不少高质量的面试题以及开发技术难题,欢迎读者入群进行交流。
致谢
  首先感谢卞诚君老师,没有他的指导和帮助,就不会有《Netty、Redis、ZooKeeper高并发实战》1一书的面世,更不会有后续的本书。
  然后感谢《Netty、Redis、ZooKeeper高并发实战》一书的读者,是他们对该书的高度评价,极大地提升了笔者的写作自信,激励笔者推出了三卷本《Java高并发核心编程》,本书为第2卷。
  最后感谢“疯狂创客圈”社群中的开发小伙伴们,他们中有很多非常有前途的技术狂人,他们对Java高并发技术的高涨热情和孜孜以求让笔者惊叹不已。欢迎大家进入“疯狂创客圈”社群(QQ群为104131248)积极“砸”问题,虽然有的技术难题笔者不一定能给出最佳的解决方案,但坦诚、纯粹的技术交流,能让大家相互启发,产生技术灵感,拓展技术视野,并最终提升技术水平。

  尼 恩
  2021年1月29日
  
该书已由机械工业出版社出版,书号为978-7-111-63290-0。—编辑注

上架指导

计算机\程序设计

封底文字

主要内容
浅显易懂地剖析了高并发IO的底层原理
图文并茂地介绍了TCP、HTTP、WebSocket协议的核心原理
细致深入地揭秘了Reactor高性能模式
全面介绍了Netty框架,并完成单体IM、分布式IM的实战设计
详尽地介绍了ZooKeeper、Redis的使用

图书目录

前言
自序
第1章 多线程原理与实战 1
1.1 两个技术面试故事 1
1.2 无处不在的进程和线程 2
1.2.1 进程的基本原理 3
1.2.2 线程的基本原理 5
1.2.3 进程与线程的区别 8
1.3 创建线程的4种方法 8
1.3.1 Thread类详解 8
1.3.2 创建一个空线程 10
1.3.3 线程创建方法一:继承Thread类创建线程类 12
1.3.4 线程创建方法二:实现Runnable接口创建线程目标类 13
1.3.5 优雅创建Runnable线程目标类的两种方式 16
1.3.6 通过实现Runnable接口的方式创建线程目标类的优缺点 18
1.3.7 线程创建方法三:使用Callable和FutureTask创建线程 23
1.3.8 线程创建方法四:通过线程池创建线程 28
1.4 线程的核心原理 31
1.4.1 线程的调度与时间片 31
1.4.2 线程的优先级 32
1.4.3 线程的生命周期 35
1.4.4 一个线程状态的简单演示案例 37
1.4.5 使用Jstack工具查看线程状态 40
1.5 线程的基本操作 41
1.5.1 线程名称的设置和获取 41
1.5.2 线程的sleep操作 43
1.5.3 线程的interrupt操作 45
1.5.4 线程的join操作 48
1.5.5 线程的yield操作 53
1.5.6 线程的daemon操作 55
1.5.7 线程状态总结 61
1.6 线程池原理与实战 62
1.6.1 JUC的线程池架构 63
1.6.2 Executors的4种快捷创建线程池的方法 65
1.6.3 线程池的标准创建方式 72
1.6.4 向线程池提交任务的两种方式 73
1.6.5 线程池的任务调度流程 77
1.6.6 ThreadFactory(线程工厂) 79
1.6.7 任务阻塞队列 81
1.6.8 调度器的钩子方法 82
1.6.9 线程池的拒绝策略 84
1.6.10 线程池的优雅关闭 87
1.6.11 Executors快捷创建线程池的潜在问题 93
1.7 确定线程池的线程数 97
1.7.1 按照任务类型对线程池进行分类 97
1.7.2 为IO密集型任务确定线程数 98
1.7.3 为CPU密集型任务确定线程数 100
1.7.4 为混合型任务确定线程数 101
1.8 ThreadLocal原理与实战 104
1.8.1 ThreadLocal的基本使用 104
1.8.2 ThreadLocal的使用场景 107
1.8.3 使用ThreadLocal进行线程隔离 108
1.8.4 使用ThreadLocal进行跨函数数据传递 109
1.8.5 ThreadLocal内部结构演进 110
1.8.6 ThreadLocal源码分析 111
1.8.7 ThreadLocalMap源码分析 114
1.8.8 ThreadLocal综合使用案例 119
第2章 Java内置锁的核心原理 123
2.1 线程安全问题 123
2.1.1 自增运算不是线程安全的 123
2.1.2 临界区资源与临界区代码段 126
2.2 synchronized关键字 127
2.2.1 synchronized同步方法 127
2.2.2 synchronized同步块 128
2.2.3 静态的同步方法 130
2.3 生产者-消费者问题 131
2.3.1 生产者-消费者模式 131
2.3.2 一个线程不安全的实现版本 132
2.3.3 一个线程安全的实现版本 139
2.4 Java对象结构与内置锁 140
2.4.1 Java对象结构 141
2.4.2 Mark Word的结构信息 143
2.4.3 使用JOL工具查看对象的布局 145
2.4.4 大小端问题 149
2.4.5 无锁、偏向锁、轻量级锁和重量级锁 150
2.5 偏向锁的原理与实战 152
2.5.1 偏向锁的核心原理 152
2.5.2 偏向锁的演示案例 152
2.5.3 偏向锁的膨胀和撤销 156
2.6 轻量级锁的原理与实战 157
2.6.1 轻量级锁的核心原理 157
2.6.2 轻量级锁的演示案例 158
2.6.3 轻量级锁的分类 161
2.6.4 轻量级锁的膨胀 162
2.7 重量级锁的原理与实战 162
2.7.1 重量级锁的核心原理 162
2.7.2 重量级锁的开销 165
2.7.3 重量级锁的演示案例 166
2.8 偏向锁、轻量级锁与重量级锁的对比 169
2.9 线程间通信 170
2.9.1 线程间通信的定义 170
2.9.2 低效的线程轮询 170
2.9.3 wait方法和notify方法的原理 171
2.9.4 “等待-通知”通信模式演示案例 174
2.9.5 生产者-消费者之间的线程间通信 177
2.9.6 需要在synchronized同步块的内部使用wait和notify 180
第3章 CAS原理与JUC原子类 182
3.1 什么是CAS 182
3.1.1 Unsafe类中的CAS方法 182
3.1.2 使用CAS进行无锁编程 185
3.1.3 使用无锁编程实现轻量级安全自增 186
3.1.4 字段偏移量的计算 189
3.2 JUC原子类 191
3.2.1 JUC中的Atomic原子操作包 191
3.2.2 基础原子类AtomicInteger 192
3.2.3 数组原子类AtomicIntegerArray 194
3.2.4 AtomicInteger线程安全原理 195
3.3 对象操作的原子性 198
3.3.1 引用类型原子类 198
3.3.2 属性更新原子类 200
3.4 ABA问题 201
3.4.1 了解ABA问题 201
3.4.2 ABA问题解决方案 203
3.4.3 使用AtomicStampedReference解决ABA问题 203
3.4.4 使用AtomicMarkableReference解决ABA问题 205
3.5 提升高并发场景下CAS操作的性能 207
3.5.1 以空间换时间:LongAdder 208
3.5.2 LongAdder的原理 211
3.6 CAS在JDK中的广泛应用 218
3.6.1 CAS操作的弊端和规避措施 218
3.6.2 CAS操作在JDK中的应用 219
第4章 可见性与有序性的原理 220
4.1 CPU物理缓存结构 220
4.2 并发编程的三大问题 222
4.2.1 原子性问题 222
4.2.2 可见性问题 223
4.2.3 有序性问题 224
4.3 硬件层的MESI协议原理 227
4.3.1 总线锁和缓存锁 228
4.3.2 MSI协议 230
4.3.3 MESI协议及RFO请求 230
4.3.4 volatile的原理 234
4.4 有序性与内存屏障 237
4.4.1 重排序 237
4.4.2 As-if-Serial规则 238
4.4.3 硬件层面的内存屏障 240
4.5 JMM详解 242
4.5.1 什么是Java内存模型 243
4.5.2 JMM与JVM物理内存的区别 244
4.5.3 JMM的8个操作 246
4.5.4 JMM如何解决有序性问题 248
4.5.5 volatile语义中的内存屏障 250
4.6 Happens-Before规则 251
4.6.1 Happens-Before规则介绍 252
4.6.2 规则1:顺序性规则 252
4.6.3 规则2:volatile规则 252
4.6.4 规则3:传递性规则 255
4.6.5 规则4:监视锁规则 255
4.6.6 规则5:start()规则 256
4.6.7 规则6:join()规则 257
4.7 volatile不具备原子性 258
4.7.1 volatile变量的自增实例 258
4.7.2 volatile变量的复合操作不具备原子性的原理 260
第5章 JUC显式锁的原理与实战 262
5.1 显式锁 262
5.1.1 显式锁Lock接口 263
5.1.2 可重入锁ReentrantLock 264
5.1.3 使用显式锁的模板代码 267
5.1.4 基于显式锁进行“等待-通知”方式的线程间通信 269
5.1.5 LockSupport 273
5.1.6 显式锁的分类 276
5.2 悲观锁和乐观锁 279
5.2.1 悲观锁存在的问题 279
5.2.2 通过CAS实现乐观锁 279
5.2.3 不可重入的自旋锁 280
5.2.4 可重入的自旋锁 281
5.2.5 CAS可能导致“总线风暴” 283
5.2.6 CLH自旋锁 285
5.3 公平锁与非公平锁 293
5.3.1 非公平锁实战 293
5.3.2 公平锁实战 295
5.4 可中断锁与不可中断锁 296
5.4.1 锁的可中断抢占 296
5.4.2 死锁的监测与中断 298
5.5 共享锁与独占锁 302
5.5.1 独占锁 302
5.5.2 共享锁Semaphore 302
5.5.3 共享锁CountDownLatch 306
5.6 读写锁 307
5.6.1 读写锁ReentrantReadWriteLock 308
5.6.2 锁的升级与降级 310
5.6.3 StampedLock 312
第6章 AQS抽象同步器的核心原理 316
6.1 锁与队列的关系 316
6.2 AQS的核心成员 318
6.2.1 状态标志位 318
6.2.2 队列节点类 319
6.2.3 FIFO双向同步队列 321
6.2.4 JUC显式锁与AQS的关系 322
6.2.5 ReentrantLock与AQS的组合关系 322
6.3 AQS中的模板模式 325
6.3.1 模板模式 325
6.3.2 一个模板模式的参考实现 326
6.3.3 AQS的模板流程 329
6.3.4 AQS中的钩子方法 329
6.4 通过AQS实现一把简单的独占锁 331
6.4.1 简单的独占锁的UML类图 331
6.4.2 简单的独占锁的实现 331
6.4.3 SimpleMockLock测试用例 333
6.5 AQS锁抢占的原理 335
6.5.1 显式锁抢占的总体流程 335
6.5.2 AQS模板方法:acquire(arg) 336
6.5.3 钩子实现:tryAcquire(arg) 336
6.5.4 直接入队:addWaiter 337
6.5.5 自旋入队:enq 338
6.5.6 自旋抢占:acquireQueued() 339
6.5.7 挂起预判:shouldParkAfterFailedAcquire() 340
6.5.8 线程挂起:parkAndCheckInterrupt() 342
6.6 AQS的两个关键点:节点的入队和出队 343
6.6.1 节点的自旋入队 343
6.6.2 节点的出队 343
6.7 AQS锁释放的原理 345
6.7.1 SimpleMockLock独占锁的释放流程 345
6.7.2 AQS模板方法:release() 345
6.7.3 钩子实现:tryRelease() 346
6.7.4 唤醒后继:unparkSuccessor() 346
6.8 ReentrantLock的抢锁流程 347
6.8.1 ReentrantLock非公平锁的抢占流程 347
6.8.2 非公平锁的同步器子类 348
6.8.3 非公平抢占的钩子方法:tryAcquire(arg) 349
6.8.4 ReentrantLock公平锁的抢占流程 350
6.8.5 公平锁的同步器子类 350
6.8.6 公平抢占的钩子方法:tryAcquire(arg) 351
6.8.7 是否有后继节点的判断 351
6.9 AQS条件队列 352
6.9.1 Condition基本原理 352
6.9.2 await()等待方法原理 353
6.9.3 signal()唤醒方法原理 355
6.10 AQS的实际应用 356
第7章 JUC容器类 358
7.1 线程安全的同步容器类 358
7.2 JUC高并发容器 360
7.3 CopyOnWriteArrayList 362
7.3.1 CopyOnWriteArrayList的使用 362
7.3.2 CopyOnWriteArrayList的原理 364
7.3.3 CopyOnWriteArrayList 读取操作 366
7.3.4 CopyOnWriteArrayList写入操作 366
7.3.5 CopyOnWriteArrayList的迭代器实现 367
7.4 BlockingQueue 368
7.4.1 BlockingQueue的特点 368
7.4.2 阻塞队列的常用方法 368
7.4.3 常见的BlockingQueue 370
7.4.4 ArrayBlockingQueue的基本使用 372
7.4.5 ArrayBlockingQueue构造器和成员 374
7.4.6 非阻塞式添加元素:add()、offer()方法的原理 376
7.4.7 阻塞式添加元素:put()方法的原理 378
7.4.8 非阻塞式删除元素:poll()方法的原理 380
7.4.9 阻塞式删除元素:take()方法的原理 381
7.4.10 peek()直接返回当前队列的头元素 382
7.5 ConcurrentHashMap 383
7.5.1 HashMap和HashTable的问题 383
7.5.2 JDK 1.7版本ConcurrentHashMap的结构 384
7.5.3 JDK 1.7版本ConcurrentHashMap的核心原理 385
7.5.4 JDK 1.8版本ConcurrentHashMap的结构 393
7.5.5 JDK 1.8版本ConcurrentHashMap的核心原理 395
7.5.6 JDK 1.8版本ConcurrentHashMap的核心源码 398
第8章 高并发设计模式 402
8.1 线程安全的单例模式 402
8.1.1 从饿汉式单例到懒汉式单例 402
8.1.2 使用内置锁保护懒汉式单例 404
8.1.3 双重检查锁单例模式 404
8.1.4 使用双重检查锁+volatile 405
8.1.5 使用静态内部类实现懒汉式单例模式 406
8.2 Master-Worker模式 407
8.2.1 Master-Worker模式的参考实现 408
8.2.2 Netty中Master-Worker模式的实现 413
8.2.3 Nginx中Master-Worker模式的实现 414
8.3 ForkJoin模式 415
8.3.1 ForkJoin模式的原理 415
8.3.2 ForkJoin框架 416
8.3.3 ForkJoin框架使用实战 416
8.3.4 ForkJoin框架的核心API 419
8.3.5 工作窃取算法 421
8.3.6 ForkJoin框架的原理 423
8.4 生产者-消费者模式 423
8.5 Future模式 424
第9章 高并发核心模式之异步回调模式 426
9.1 从泡茶的案例讲起 426
9.2 join:异步阻塞之闷葫芦 427
9.2.1 线程的合并流程 427
9.2.2 调用join()实现异步泡茶喝 427
9.2.3 join()方法详解 429
9.3 FutureTask:异步调用之重武器 430
9.3.1 通过FutureTask获取异步执行结果的步骤 431
9.3.2 使用FutureTask实现异步泡茶喝 431
9.4 异步回调与主动调用 434
9.5 Guava的异步回调模式 435
9.5.1 详解FutureCallback 435
9.5.2 详解ListenableFuture 436
9.5.3 ListenableFuture异步任务 437
9.5.4 使用Guava实现泡茶喝的实例 438
9.5.5 Guava异步回调和Java异步调用的区别 442
9.6 Netty的异步回调模式 442
9.6.1 GenericFutureListener接口详解 443
9.6.2 Netty的Future接口详解 443
9.6.3 ChannelFuture的使用 444
9.6.4 Netty的出站和入站异步回调 444
9.7 异步回调模式小结 445
第10章 CompletableFuture异步回调 446
10.1 CompletableFuture详解 446
10.1.1 CompletableFuture的UML类关系 446
10.1.2 CompletionStage接口 447
10.1.3 使用runAsync和supplyAsync创建子任务 448
10.1.4 设置子任务回调钩子 449
10.1.5 调用handle()方法统一处理异常和结果 451
10.1.6 线程池的使用 452
10.2 异步任务的串行执行 453
10.2.1 thenApply()方法 453
10.2.2 thenRun()方法 455
10.2.3 thenAccept()方法 455
10.2.4 thenCompose()方法 456
10.2.5 4个任务串行方法的区别 458
10.3 异步任务的合并执行 458
10.3.1 thenCombine()方法 458
10.3.2 runAfterBoth()方法 460
10.3.3 thenAcceptBoth()方法 461
10.3.4 allOf()等待所有的任务结束 462
10.4 异步任务的选择执行 463
10.4.1 applyToEither()方法 463
10.4.2 runAfterEither()方法 465
10.4.3 acceptEither()方法 465
10.5 CompletableFuture的综合案例 466
10.5.1 使用CompletableFuture实现泡茶喝实例 466
10.5.2 使用CompletableFuture进行多个RPC调用 468
10.5.3 使用RxJava模拟RPC异步回调 469

教学资源推荐
作者: 赵宏,陈旭东,马迪芳
作者: Y. Daniel Liang
作者: [美]基普·欧文(Kip Irvine) 著
参考读物推荐
作者: Michael Juntao Yuan Kevin Sharp
作者: 张军
作者: (澳)Quinton Anderson 著
作者: [美] 托马兹·卓巴斯(Tomasz Drabas) 丹尼·李(Denny Lee) 著