Java高并发与集合框架:JCF和JUC源码分析与实现pdf下载pdf下载

Java高并发与集合框架:JCF和JUC源码分析与实现百度网盘pdf下载

作者:
简介:本篇主要提供Java高并发与集合框架:JCF和JUC源码分析与实现pdf下载
出版社:电子工业出版社
出版时间:2022-01
pdf下载价格:0.00¥

免费下载


书籍下载


内容介绍

编辑推荐

适读人群 :本书分为3部分,第1部分为Java编程入门知识,方便初学者对JCF相关知识进行查漏补缺,第2 部分和第3部分对基础知识有一定的要求,适合有一些Java编程基础的技术人员阅读。

1.本书主要对Java集合框架(JCF)和Java并发工具包(JUC)进行介绍,包括它们的适用场景、使用方法、技术理论和运行原理。

2.根据二八法则,掌握Java集合框架和Java集合框架,轻松应对80%的工作场景。

3.本书思路清晰、由浅入深、通俗易懂、讲解细致,帮助读者轻松掌握相关知识点。

内容简介

本书主要对Java集合框架(JCF)和Java并发工具包(JUC)进行介绍,包括它们的适用场景、使用方法、技术理论和运行原理。为了让读者能够轻松阅读本书,本书中所有内容都采用由浅入深的方式进行介绍,先保证读者会用这些技术,再介绍这些技术的运行原理。

本书分为3部分,第1部分为Java编程入门知识,方便初学者对JCF相关知识进行查漏补缺,第2 部分和第3部分对基础知识有一定的要求,适合有一些Java编程基础的技术人员阅读。

作者简介

银文杰

笔名“说好不能打脸”,CSDN专栏作者,CSDN Java特约编辑,《高性能服务系统构建与实战》一书作者。16年资深IT“直男”一枚,爱好是敲敲代码、写写博客、研究创业热点。

参与过多个百万级用户系统的设计研发,对系统顶层设计、技术线路规划、系统性能调优、业务抽象等有较丰富的经验。也曾有几年头脑发热拍案创业,兼职过市场销售、电话客服、公司保安及清洁大叔。


精彩书评

本人见证了这本书从设想到成书的整个过程。有的人觉得写程序很苦,只是一份谋生的工作;而有的人觉得很酷,那是他们发自内心的热爱,作者属于后者。这是一本心血之作,值得希望进阶的Java程序员好好研读。

——博智维讯CEO 唐伟


这本书字里行间都是作者通过实践获得的体系化的总结与思考。如果你在Java集合框架(JCF)和Java并发工具包(JUC)的使用中遇到过具体的技术方案匹配等问题,那么一定能从这本书中获益;如果你希望了解它们的工作原理,那么更要逐章认真阅读这本书。

——IBM SmartCloud初创组成员,青云科技CEO 黄允松


作为Java程序员,虽然在我们的技术体系中JCF和JUC的知识可能还不到10%,但是我们工作中80%的场景都离不开它们。根据2/8法则,我们有充分的理由好好吃透JCF和JUC,如果你还没准备好,那么这本书正提供了这样难得的机会。

——华为20级软件教练,《代码精进之路:从码农到工匠》作者 张建飞


目录

目录


第I部分 Java集合框架 1
第1章 JCF中的List集合 3
1.1 List集合概要和重要接口介绍 3
1.1.1 java.lang.Iterable接口 4
1.1.2 java.util.Collection接口 5
1.1.3 java.util.AbstractList抽象类 6
1.1.4 java.util.RandomAccess接口 7
1.2 List集合实现――Vector 14
1.2.1 Vector集合的扩容操作 16
1.2.2 Vector集合的修改方法――set(int, E) 19
1.2.3 Vector集合的删除方法――removeElementAt(int) 20
1.3 List集合实现――ArrayList 22
1.3.1 ArrayList集合概述 23
1.3.2 ArrayList集合的初始化操作和扩容操作 23
1.3.3 ArrayList集合中的add(E)方法 26
1.3.4 Vector集合与ArrayList集合对比 28
1.4 List集合实现――Stack 29
1.5 List集合实现――LinkedList 32
1.5.1 LinkedList集合的主要结构 33
1.5.2 LinkedList集合的添加操作 35
1.5.3 LinkedList集合的移除操作 40
1.5.4 LinkedList集合的查找操作 44
1.5.5 使用LinkedList集合的栈工作特性 46
1.6 LinkedList集合与ArrayList集合的对比 48
1.6.1 两种集合写操作性能的比较 48
1.6.2 两种集合读操作性能的比较 49
1.6.3 不同遍历方式对LinkedList集合的意义 50
1.6.4 在什么场景中推荐选择LinkedList集合 54
第2章 JCF中的Queue、Deque集合 55
2.1 Queue集合实现――ArrayDeque 56
2.1.1 ArrayDeque集合的主要结构及相关方法 57
2.1.2 ArrayDeque集合的初始化过程 60
2.1.3 ArrayDeque集合的添加操作 61
2.1.4 ArrayDeque集合的扩容操作 64
2.2 堆和堆排序 67
2.2.1 树、二叉树 67
2.2.2 堆、小顶堆、大顶堆 69
2.2.3 堆的降维――使用数组表示堆结构 71
2.2.4 堆排序 72
2.2.5 自行完成一个堆排序 75
2.3 Queue集合实现――PriorityQueue 77
2.3.1 PriorityQueue队列的基本使用方法 77
2.3.2 PriorityQueue队列的构造 78
2.3.3 PriorityQueue队列的核心工作原理 82
2.3.4 PriorityQueue队列的扩容操作 88
2.3.5 PriorityQueue队列的添加操作 90
2.3.6 PriorityQueue队列的移除操作 90
第3章 JCF中的Map集合 94
3.1 Map集合概述 94
3.1.1 K-V键值对节点定义――Entry 95
3.1.2 与Map集合有关的重要接口和抽象类 97
3.2 红黑树略讲 103
3.2.1 二叉查找树(二叉搜索树) 104
3.2.2 二叉查找树的查找操作和添加操作 105
3.2.3 为什么需要红黑树 107
3.2.4 红黑树的基本结构 107
3.2.5 红黑树的操作规则 108
3.2.6 红黑树的节点添加操作 110
3.2.7 红黑树的节点删除操作 120
3.3 Map集合实现――TreeMap 136
3.3.1 TreeMap集合的基本使用方法 136
3.3.2 TreeMap集合的重要属性和方法 138
3.4 Map集合实现――HashMap 148
3.4.1 HashMap集合的结构 150
3.4.2 HashMap集合的主要工作过程 155
3.4.3 向HashMap集合中添加K-V键值对节点(链表方式) 158
3.4.4 向HashMap集合中添加K-V键值对节点(红黑树方式) 160
3.4.5 HashMap集合红黑树、链表互相转换 165
3.4.6 HashMap集合的扩容操作 172
3.5 Map集合实现――LinkedHashMap 180
3.5.1 LinkedHashMap集合的节点结构 182
3.5.2 LinkedHashMap集合的主要结构 184
3.5.3 LinkedHashMap集合的迭代器 186
第4章 JCF的Set集合 191
4.1 Set集合概述 192
4.1.1 java.util.SortedSet接口 192
4.1.2 java.util.NavigableSet接口 195
4.1.3 java.util.AbstractSet抽象类 199
4.2 Set集合实现――HashSet 200
4.2.1 HashSet集合的主要属性 201
4.2.2 HashSet集合的构造方法 201
4.2.3 HashSet集合的主要操作方法 202
4.3 Set集合实现――LinkedHashSet、TreeSet 203
4.3.1 LinkedHashSet集合 203
4.3.2 TreeSet集合 204
第II部分 JUC与高并发概述 208
第5章 Object Monitor管程实现 212
5.1 悲观锁和乐观锁 212
5.2 synchronized修饰符和线程控制 215
5.2.1 线程的基本特点 215
5.2.2 线程状态切换和操作方法 216
5.3 Object Monitor基本结构概要 227
5.3.1 synchronized修饰符和锁升级过程 228
5.3.2 管程与synchronized修饰符 233
5.3.3 对线程状态切换示意图进行细化 235
5.4 使用jstack命令观察线程状态 237
5.4.1 jstack基本命令 237
5.4.2 jstack命令中的线程关键信息 238
5.4.3 线程状态及切换方式(仅限Object Monitor模式) 240
5.5 Object Monitor模式总结 244
5.5.1 as-if-serial语义原则与happens-before规则 244
5.5.2 Object Monitor模式如何保证三性 246
5.5.3 Object Monitor模式如何解决互斥、同步问题 248
第6章 JUC的必要组成部分 250
6.1 Unsafe工具类 252
6.1.1 在源码中使用Unsafe工具类 252
6.1.2 Unsafe工具类中的典型方法讲解 255
6.2 LockSupport工具类 261
6.2.1 park()方法和unpark()方法的使用示例 261
6.2.2 LockSupport工具类的主要属性和方法 263
6.3 线程状态 266
6.3.1 使用jstack命令观察线程状态 266
6.3.2 更详细的线程状态说明 269
6.3.3 其他常用命令 271
6.4 volatile修饰符 275
6.4.1 为什么需要Java内存模型 275
6.4.2 内存可见性问题和MESI协议 277
6.4.3 存储缓存和失效队列 281
6.4.4 内存屏障与数据一致性 283
6.4.5 内存屏障与指令重排 285
6.4.6 volatile修饰符和内存屏障 289
6.5 轻量化的原子性操作方法 300
6.5.1 原子性操作――AtomicInteger类 301
6.5.2 原子性操作――AtomicStampedReference类 301
6.5.3 使用变量句柄完成原子性操作 303
第7章 另一种管程实现――AQS技术 305
7.1 AQS技术的基本原理 306
7.1.1 AQS技术的工作过程概要及使用示例 306
7.1.2 AQS技术中的关键定义 308
7.2 AQS实现――ReentrantLock类 325
7.2.1 ReentrantLock类的使用方法 325
7.2.2 AQS技术如何帮助ReentrantLock类工作 327
7.3 AQS实现――Condition控制 332
7.3.1 基本使用方法 332
7.3.2 ReentrantLock类如何进行Condition控制 334
7.4 AQS技术总结 342
第III部分 在高并发场景中工作的集合 345
第8章 高并发场景中的List、Map和Set集合 346
8.1 List集合实现――CopyOnWriteArrayList 346
8.1.1 CopyOnWriteArrayList集合概述 346
8.1.2 CopyOnWriteArrayList集合的主要构造方法 348
8.1.3 CopyOnWriteArrayList集合的主要方法 349
8.1.4 java.util.Collections.synchronizedList()方法的补充作用 352
8.2 Map集合实现――ConcurrentHashMap 355
8.2.1 ConcurrentHashMap集合概述 355
8.2.2 ConcurrentHashMap集合的主要属性 358
8.2.3 ConcurrentHashMap集合的主要工作过程 359
8.3 高并发场景中的List、Map、Set集合说明 378
第9章 高并发场景中的Queue集合 380
9.1 概述 380
9.1.1 什么是有界队列,什么是无界队列 381
9.1.2 什么是阻塞队列,什么是非阻塞队列 382
9.2 Queue集合实现――ArrayBlockingQueue 384
9.2.1 ArrayBlockingQueue队列的基本使用方法 385
9.2.2 ArrayBlockingQueue队列的工作原理 388
9.3 Queue集合实现――LinkedBlockingQueue 396
9.3.1 LinkedBlockingQueue队列的重要属性 397
9.3.2 LinkedBlockingQueue队列的构造方法 399
9.3.3 入队操作和出队操作 401
9.3.4 LinkedBlockingQueue队列的主要方法 404
9.4 Queue集合实现――LinkedTransferQueue 413
9.4.1 LinkedTransferQueue队列的基本使用场景 414
9.4.2 LinkedTransferQueue队列的主要结构 416
9.4.3 LinkedTransferQueue队列的主要工作过程 420
9.4.4 LinkedTransferQueue队列的主要方法 437
9.5 Queue集合实现――PriorityBlockingQueue 438
9.5.1 PriorityBlockingQueue队列的主要属性 439
9.5.2 PriorityBlockingQueue队列的主要构造方法 440
9.5.3 PriorityBlockingQueue队列的扩容过程 442
9.5.4 PriorityBlockingQueue队列的典型操作方法 444
9.6 Queue集合实现――DelayQueue 446
9.6.1 java.util.concurrent.Delayed接口与基本使用方法 447
9.6.2 DelayQueue队列的主要属性和构造方法 449
9.6.3 DelayQueue队列的主要工作过程 450
第10章 高并发场景中的集合总结 454
10.1 还有哪些高并发场景中的常用集合没有被提及 454
10.2 典型集合对应关系对比 455
10.3 高并发场景中的集合可借鉴的设计思想 455
10.3.1 使用JUC提供的基本要素保证线程安全性 456
10.3.2 通过复合手段保证多场景中的性能平衡性 457
10.3.3 更多提升性能的手段 458

前言/序言

前言


1.写在开篇

为什么撰写本书

笔者一直在信息系统建设的一线工作,承担过多种不同的工作职责。在工作中,笔者经常和掌握不同技术的朋友讨论具体问题的解决方案,发现在Java体系中,大家使用最多的是Java集合框架(JCF)和Java并发工具包(JUC)。实际上,JCF和JUC已经能够覆盖笔者及朋友们工作中遇到的超过8成的应用场景,但是大家往往无法快速匹配最合适的技术方案。此外,在JCF和JUC中存在大量可以在实际工作中借鉴的设计方案,虽然网络上有一些零散的关于集合的介绍,但深入讲解其工作原理的内容并不多,甚至有一些资料存在质量问题。

笔者“撸码”近17年,庆幸头未秃、智未衰。于是笔者在1年前产生了这样的想法,希望将自己在实际工作中梳理、总结的JCF、JUC的相关知识成体系地介绍给大家,也希望将自己在阅读JDK源码(包括JCF、JUC、I/O、NET等模块)后总结和思考的可用于实际工作的技术手段成体系地分享给大家。

有了想法,便着手行动,经过大半年的整理、撰写、调整,终成本书。因个人水平有限,书中难免有错误和疏漏之处,希望各位读者能诚意指出、不吝赐教。此外,各位读者可以直接通过笔者的邮箱yin-wen-jie@163.com联系笔者本人。

关于本书选择的JDK版本

由于JDK版本迭代速度较快,本书的整理和撰写又需要一个较长的时间,并且书中内容包括大量源码分析和讲解,因此本书首先要解决的问题,就是选定一个本书进行源码讲解和分析所依据的JDK版本。

这个问题需要从JDK版本的更新特点、大家使用JDK版本的习惯和撰写本书的目的来考虑,目前大家在实际工作中使用最多的版本是JDK 1.8和JDK 11,并且出于对Oracle商业运作的考虑,JDK 11之后的升级版本已不再免费提供,因此大家在生产环境中一般使用Open JDK作为运行环境。同样出于对Oracle商业运作的考虑,JDK版本的发布周期固定为每半年发布一个大版本、每3年发布一个LTS/LMS版本(长期支持版本),截至2021年4月,JDK 16已经发布(JDK 16是一个短期过渡版本),紧接着2021年9月,JDK 17正式发布(这是一个LTS/LMS版本),这显然加大了读者学习和筛选JDK版本的工作量。

好消息是Oracle基本开源了所有已成熟的JDK版本,是否商业化运行并不会影响我们对这些JDK源码的学习(只要不用于商业用途),而且JDK版本的向下兼容性保证了读者在了解JDK的工作原理后,可以将其应用到自己正在使用的JDK版本上。此外,越新的JDK版本对关键数据结构、关键算法实现过程的优化越多,本书希望在讲解过程中,可以尽可能多地将这些有益的优化点介绍给读者。

在综合考虑各因素后,本书将JDK 14作为本书讲解源码依据的主要版本(在后续内容中,如果不特别说明,那么代码分析都是基于JDK 14进行的)。JDK 14是在整理、编写本书时发布的版本。在该版本中,与本书主要内容有关的数据结构、核心算法、设计方案和之前的版本基本保持稳定和兼容,便于读者在常用的JDK 1.8、JDK 11中找到对应的实现位置。本书介绍的JDK 14中的源码内容是完全开源的,读者可以在Oracle官方网站直接下载这些源码。

本书的目标读者

本书前半部分可以作为Java编程的入门学习内容,也可以作为初学者进行JCF部分知识查漏补缺的参考资料;本书后半部分对基础知识有一定的要求,适合有一些Java编程基础的程序员阅读。此外,本书可以作为程序员对JCF部分和JUC部分知识结构进行梳理的参考用书。

2.本书约定

1)关于源码注释及代码格式。

本书中有大量基于JDK 14的源码片段。笔者会对这些源码片段逐段说明、逐条分析,读者不用担心无法读懂这些源码。此外,大部分章节在对源码进行分析后,会使用图文方式对源码中的重要知识点进行归纳和总结。

引用大量的源码会占用篇幅。为了尽可能节约纸张,本书中的示例代码没有遵循Java官方推荐的注释规范和代码格式规范,本书会对代码和注释进行格式压缩。本书主要采用以下两种格式压缩方式。

 采用单行注释代替多行注释。

Java官方推荐的多行注释方式采用的是“/***/”,如下所示。

/**

* Creates a new, empty map with an initial table size

* accommodating the specified number of elements without the need

* to dynamically resize.

*

* @throws IllegalArgumentException if the initial capacity of

* elements is negative

*/

这种注释方式非常清晰且容易阅读,但是占用了过长的篇幅,所以本书会将上述注释转换为单行注释,如下所示。

// Basic hash bin node, used for most entries.

// (See below for TreeNode subclass, and in LinkedHashMap for its Entry

// subclass.)

 采用压缩格式替换单行代码块。

如果代码块中只有一行代码,那么Java允许省略代码块中的大括号“{}”。例如,在if语句的代码块中,如果只有一行执行代码,则可以采用如下方式进行书写。

if (c == 0)

result = v;

但这种书写方式容易在排布紧凑的局部位置引起阅读障碍,所以针对源码中的这种简写方式,本书进行了简写还原和格式压缩。书中会恢复所有被简写的代码段落的大括号“{}”,从而方便对源码进行分析,并且将只有一行代码的代码块压缩成单行,如下所示。

if (s == elementData.length) {

elementData = grow();

}

// 或者

if (s == elementData.length) { elementData = grow(); }

2)关于JDK版本的命名。

JDK 1.2~JDK 1.8都采用1.X格式的小版本号,但是在JDK 1.8后,Oracle改为采用大版本号对其进行命名,如JDK 9、JDK 11等。本书也会采用这种命名方式,但是由于各个版本功能存在差异,因此为了表达从某个JDK版本开始支持某种功能或特性,本书会采用“+”符号表示。例如,如果要表达从JDK 1.8开始支持某种特性,则用JDK 1.8+表示;如果要表达从JDK 11开始支持某种特性,则用JDK 11+表示。

3)其他约定。

 关于JVM的称呼约定。

本书无意深入分析JVM的内部运行原理,也不会深入讨论JVM每个模块负责的具体工作。例如,本书不会分析JIT(即时编译器)指令重排的细节,以及在什么情况下代码指令不会被编译执行,而会被解释执行。凡是涉及内部运行原理的内容,本书将其统称为JVM运行过程。此外,如果没有特别说明,那么本书提到的JVM都表示HotSpot版本的虚拟机。

 关于方法的称呼约定。

由于Java中的方法涉及多态场景,因此本书需要保证对Java中方法的称呼不出现二义性。例如,java.lang.Object类中的wait()方法存在多态表达,代码如下。

wait() throws InterruptedException


wait(long timeoutMillis) throws InterruptedException


wait(long timeoutMillis, int nanos) throws InterruptedException

在不产生二义性的情况下,本书会直接采用“wait()方法”的描述方式。如果需要介绍多态场景中方法名相同、入参不同的方法表达的不同工作特性,那么不加区别就会造成二义性,这时本书会采用“wait()”“wait(long)”分别进行特定描述。

 关于图表的约定。

本书主要采用图文方式对Java源码进行说明、分析和总结,由于客观限制,大量的插图只能采用黑白方式呈现,因此如果有需要,则会在插图后的正文中或插图右上角给出图例说明。

 关于System.out对象的使用。

在实际工作中,推荐使用slf4j-log4j方式进行日志/控制台输出,但本书中的代码片段大量使用System.out对象进行控制台输出,这并不影响读者理解这些代码片段的逻辑,也有利于不同知识水平的读者将精力集中在理解核心思路上。

 关于包简写的约定。

本书大部分内容涉及Java集合框架(JCF)和Java并发工具包(JUC),JCF和JUC通常涉及较长的包路径。例如,在JUC中,封装后最终向程序员开放的原子性操作工具类位于java.util.concurrent.atomic包下。如果本书中每一个类的全称都携带这么长的包路径,那么显然是没必要的。为了节约篇幅,本书会使用包路径下每个路径点的首字母对包路径进行简写,如将“java.util.concurrent.atomic”包简写为j.u.c.atomic包。

 关于集合、集合对象、队列的约定。

读者应该都已经知晓,对象是类的实例。本书将JCF中的具体类称为集合,将JCF中类的实例对象称为集合对象。队列是一种具有特定工作效果的集合,从继承结构上来说,本书会将JCF中实现了java.util.Queue接口的集合称为队列。这主要是为了表述方便,并不代表笔者认为集合、集合对象和队列在JVM工作原理层面上有任何差异。

3.必要的前置知识

本书难度适中,但仍然需要读者对Java编程语言具备基本认知,这样才能通畅地阅读本书所有内容。这种基本认知与工作年限没有关系,属于只要是Java程序员就应该掌握的知识。

1)关于位运算的知识。

Java支持基于二进制的位运算操作。在Java中,使用“>>”表示无符号位的右移运算,使用“>>>”表示有符号位的右移运算,使用“<<”表示无符号位的左移运算,使用“<<<”表示有符号位的左移运算。

在Java中,基于整数的位运算相当于整数的乘法运算或除法运算。如“x >> 1”表示将x除以2,“x << 1”表示将x乘以2。在JCF中,无论是哪个版本的Java源码,都会采用位运算来实现整数与2的乘法运算或除法运算。此外,读者需要知道如何对某个负整数进行二进制表达。在特定情况下,Java使用与运算替换取余运算。例如,通过语句“x & 255”可实现取余运算,这句代码的意义为对256取余。

2)关于对象引用、引用传递和“相等”的知识。

Java中有八种基础类型和类类型,可以使用引用的方式给类的对象赋值。在调用方法时,除八种基础类型的变量外,传递的都是对象引用(包括基于基础类型的数组对象)。

Java中的“相等”有两种含义,一种是值相等,另一种是引用地址相等。值相等是由对象中的 equals()方法和 hashCode()方法配合实现的(如果两个对象的值相等,那么使用equals()方法对这两个对象进行比较会返回true,并且使用hashCode()方法对这两个对象进行比较返回的int类型的值也必然相同);引用地址相等是由两个对象(注意:不是基本类型数据)使用“==”运算符进行比较得到的。

本书虽然未涉及动态常量池、字符串常量池的相关知识,但需要读者知晓这些,否则无法理解类似于“String”的字符串对象或基础类型装箱后的对象关于“相等”的工作原理。

3)关于对象序列化和反序列化的知识。

Java的序列化和反序列化过程主要是指由java.io包支持的将对象转换为字节序列并输出的过程和将字节序列转换为对象并输入的过程。JCF 中的大部分集合都对对象的序列化和反序列化过程进行了重新实现。其中要解决的问题有很多,包括提高各种集合在序列化和反序列化过程中的性能问题(这个很关键,因为集合中通常存储了大量数据),以及如何保证集合在不同JDK版本中进行反序列化时的兼容性问题。

本书不会专门讲解每一种集合在序列化和反序列化过程中的工作细节,以及如何解决上述问题,并且默认读者知晓 Java 中的对象可以使用 writeObject(ObjectOutputStream)方法和readObject(ObjectInputStream)方法对序列化和反序列化过程进行干预。

4)关于线程的知识。

为了介绍在高并发场景中工作的集合,本书会先介绍Java并发工具包(JUC)中的相关知识点,所以读者需要知道Java中的基本线程使用方法,如如何创建和运行一个用户线程。

5)关于原子性操作的基础知识。

在阅读本书前,读者无须知道引起原子性操作问题的底层原因,但需要知道Java并不能保证所有场景中的原子性操作。例如,在多线程情况下,如果没有施加任何安全措施,那么Java无法保证类似于“i++”语句的原子性。

4.本书的知识结构和脉络

由于JCF和JUC有非常庞大的知识体系,因此无法用有限的篇幅覆盖所有知识点。例如,本书并未讲解JCF中的每种集合对fail-fast机制的匹配设计,也没有讲解每种集合对对象序列化和反序列化的优化设计。此外,即使要讲解指定范围内的知识点,也需要有清晰的思路和知识脉络,从而帮助读者更好地理解。因此,在正式阅读本书内容前,需要了解本书内容的介绍路径。

首先,本书会介绍最基础的集合,它们都属于 JCF 的知识范畴,分别属于List、Queue、Map和Set性质的集合,并且与JUC不存在使用场景交集。在这一部分,本书会介绍这些集合的基本工作原理(这些集合的外在功能表现各不相同,但它们的内在数据结构具备共性),并且选择其中的重要集合及其数据结构来详细讲解。

然后,本书会向在高并发场景中工作的集合进行过渡,在这一部分,本书的内容难度有所提升,所以在正式介绍这些集合前,会先介绍与之有关的高并发知识。例如,在高并发场景中如何保证原子性、可见性和有序性,Java中两种管程的工作原理和使用方法,Java为什么需要通过自行实现的管程技术解决多线程问题。实际上,这些都是JUC的相关知识。

最后,本书会介绍在高并发场景中使用的集合,这些集合主要负责两类任务,一类任务是在高并发场景中正确完成数据的存储工作并为多个线程分享数据,另一类任务是在高并发场景中主导消费者线程(从集合中读取数据的线程)和生产者线程(向集合中写入数据的线程)之间的数据传输工作。这部分主要介绍Queue/Deque集合,以及它们是如何在保证线程安全性的前提下,利用各种设计技巧提高工作效率的。

根据本书的知识逻辑,读者会从JCF部分的知识脉络过渡到JUC部分的知识脉络,最后回到JCF本身,其中涉及的集合和数据结构如图0-2所示。需要注意的是,本书不会对所有集合和数据结构进行详细讲解,而是有选择地进行详细讲解。例如,HashMap集合具有代表性,所以会对其进行详细讲解,然后在此基础上说明LinkedHashMap集合是如何对前者进行结构扩展的;对于HashSet集合,虽然该集合经常在工作中使用,但其工作原理依赖于HashMap集合,所以只会对其进行粗略讲解;为了让读者清晰理解那些适合工作在高并发场景中的集合是如何工作的,本书除了介绍Java中的两种管程技术、多线程中的三性问题等知识,还会详细介绍具有工作共性的数据结构(如堆、红黑树、数组、链表等),使读者能在高并发场景中结合数据结构进行思考和理解。