《Java并发编程的艺术》知识点目录

Java并发编程的艺术

第一章 并发编程的挑战

1.1 上下文切换

  • p1 上下文切换
  • p1 多线程一定快吗
  • p3 为什么并发执行的速度有时比串行慢
  • p3 测试上下文切换次数和时长
  • p3 如何减少上下文切换
  • P4 减少上下文切换实战

1.2 死锁

  • p5 死锁
  • p6 避免死锁的几个常见方法
  • 1.3 资源限制的挑战
  • p6 资源限制

第二章 Java并发机制的底层实现原理

2.1 volatile的应用

  • p8 volatile的定义
  • p9 一些有关volatile实现原理的cpu术语的定义
  • p9 volatile是如何实现可见性的
  • p9 Lock前缀指令在多核处理器下引发的事情
  • p10 volatile的两条实现原则
  • p10 缓存一致性和缓存锁定
  • p11 追加64字节来为volatile优化性能(解决伪共享问题)
  • p11 不应该追加到64字节的情况

2.2 synchronized的实现原理与应用

  • p12 Java中的每一个对象都可以作为锁
  • p12 synchonized在JVM中的实现原理
  • p12 Java对象头及其数据组成
  • p13 锁的升级与对比
  • p13 JavaSE1.6以后锁的四种状态级别
  • p13 偏向锁
  • p13 偏向锁的定义、使用和撤销
  • p14 偏向锁获得和撤销的流程图
  • p14 利用JVM关闭偏向锁的延迟和彻底关闭偏向锁
  • p15 轻量级锁
  • p15 轻量级锁的加锁和解锁
  • p15 轻量级锁的自旋
  • P15 争夺锁导致的锁膨胀流程图
  • p16 偏向锁、轻量级锁、重量级锁优缺点的对比

2.3 原子操作的实现原理

  • p16 缓存行、比较并交换、CPU流水线、内存顺序冲突定义
  • p17 处理器如何实现原子操作
  • p17 使用总线锁保证原子性
  • p17 使用缓存锁保证原子性
  • P18 使用循环CAS实现原子操作
  • p19 CAS实现原子操作的三大问题(ABA、循环时间长开销大、只能保证一个共享变量的原子操作)
  • p20 处理器提供的pause指令
  • p20 使用锁机制实现原子操作

第三章 Java内存模型

3.1 Java内存模型的基础

  • p21 并发编程模型的两个关键问题
  • p21 线程通信的两种方式及Java所使用的共享内存模型
  • p22 Java内存模型的抽象结构
  • p22 JMM如何控制Java线程通信
  • p22 JMM控制下两个线程通信所必须的步骤
  • p23 从源代码到指令序列的重排序
  • P24 内存屏障概念(通过指令禁止特定类型的重排序)
  • p24 并发编程模型的分类
  • p24 写缓冲区及其特性
  • p25 处理器的重排序规则
  • p26 内存屏障类型表
  • p26 happens-before简介
  • p27 happens-before与JMM关系

3.2 重排序

  • p28 数据依赖性
  • p28 as-if-serial语义
  • p29 程序顺序规则
  • p29 重排序对多线程的影响
  • p31 控制依赖关系
  • p31 编译器和处理器的猜测
  • p31 重排序缓冲

3.3 顺序一致性

  • p31 数据竞争与顺序一致性
  • p31 数据竞争
  • p32 顺序一致性
  • p32 顺序一致性内存模型
  • p33 读/写操作串行化
  • p34 程序的顺序一致性结果
  • p35 未同步程序的执行特性
  • p36 未同步程序在顺序一致性模型和JMM中执行的差异
  • p36 总线事务
  • p37 JVM不被强求对64位浮点数的写操作具有原子性

3.4 volatile的内存语义

  • p38 volatile的特性
  • p39 volatile写-读建立的happens-before关系
  • p39 volatile写-读建立的内存语义
  • p40 volatile写的内存语义
  • p41 volatile读的内存语义
  • p42 volatile内存语义的实现
  • p42 volatile重排序规则表
  • p43 volatile中基于保守策略的JMM内存屏障插入策略
  • p44 为什么要在volatile写的后面插入一个StoreLoad屏障
  • p44 编译器自动省略不必要的屏障
  • p45 X86处理器仅对写-读操作做重排序
  • p46 JSR-133为什么要增强volatile的内存语义
  • p47 volatile和锁的对比

3.5 锁的内存语义

  • p47 锁的释放-所建立的happens-before关系
  • p48 锁的释放和获取的内存语义
  • p50 锁内存语义的实现
  • p50 ReentrantLock的实现依赖于Java同步框架AQS
  • p51 公平锁加锁调用轨迹
  • p52 公平锁解锁调用轨迹
  • p52 非公平锁的内存语义实现
  • p52 CAS
  • P53 CAS是如何同时具有volatile读和volatile写的内存语义的
  • p53 intel手册对lock前缀的说明
  • p54 公平锁和非公平锁内存语义总结
  • p54 锁释放-获取内存语义的两种实现
  • p54 Concurrent包的实现
  • p54 Java线程通信的四种方式
  • p54 concurrent包的通用化实现模式
  • p55 concurrent包的实现示意图

3.6 final域的内存语义

  • p55 final域的重排序规则
  • p55 对于final域,编译器和处理器要遵守的两个重排序规则
  • p56 写final域的重排序规则
  • p57 读final域的重排序规则
  • p59 final域为引用类型时的重排序规则
  • p59 为什么final域不能从构造函数中“溢出”
  • p62 JSR-133为什么要增强final的语义

3.7 happens-before

  • p62 JMM的设计
  • p62 设计JMM时需要考虑的关键因素
  • p63 JMM对两种不同类型重排序的不同策略
  • p63 JMM设计示意图
  • p64 happens-before的定义
  • p65 happens-before规则
  • p66 start()规则
  • p66 join()规则

3.8 双重检查锁定与延迟初始化

  • p67 延迟初始化
  • p68 双重检查锁定(一个错误的优化)
  • p69 问题的根源
  • p69 intra-thread semantics(允许单线程中不影响结果的重排序)
  • p71 两个方法实现线程安全的延迟初始化
  • p71 基于volatile-利用双重检查锁定实现延迟初始化
  • p72 基于类初始化过程中的锁实现延迟初始化
  • p73 类和接口的初始化时机
  • p73 类和接口的初始化锁LC
  • p73 类和接口的初始化过程(五个阶段,下面不再列举)
  • p78 对比基于volatile的双重检查锁定的方案和基于类初始化的方案

3.9 Java内存模型综述

  • p78 处理器的内存模型
  • p79 TSO、PSO、RMO、PowerPC内存模型
  • p79 处理器内存模型特征表
  • p80 JMM插入内存屏障的示意图
  • p80 各种内存模型之间的关系
  • p80 以程序类型分类,三种JMM的内存可见性保证
  • p81 为未同步程序提供的最小安全性保障
  • p81 各种CPU内存模型的强弱对比示意图
  • p81 JSR-133 对 JDK5 之前的旧内存模型的修补
  • p82 不同内存可见性的三类程序的执行结果对比

第四章 Java并发编程基础

4.1 线程简介

  • p83 什么是线程
  • p84 为什么要使用多线程(更多的处理器核心、更快的响应时间、更好的编程模型)
  • p85 什么是线程优先级
  • p85 设置线程优先级的规律
  • p86 线程优先级不能作为程序正确性的依赖
  • p87 线程的状态
  • p89 Java线程状态变迁图
  • p90 Daemon线程(守护线程)

4.2 启动和终止线程

  • p91 构造线程
  • p92 初始化线程对象
  • p92 启动线程
  • p92 理解中断
  • p92 抛出InterruptedException之前会清除中断标识位
  • p93 过期的suspend()、resume()和stop()
  • p95 安全地终止线程

4.3 线程间通信

  • p96 volatile和synchronized关键字
  • p96 每个线程可以拥有对象/对象的成员变量的拷贝
  • p96 volatile的作用
  • p96 synchronized的作用
  • p97 synchronized关键字的实现细节
  • p97 对象的监视器(monitor)
  • p98 对象、监视器、同步队列和执行线程之间的关系
  • p98 等待/通知机制
  • p99 等待/通知相关方法
  • p100 调用wati()、notify()和notifyAll()时需要注意的细节
  • p101 等待/通知基本范式(生产者消费者问题)
  • p102 管道输入/输出流(piped)
  • p103 Thread.join()的使用
  • p105 ThreadLocal的使用

4.4 线程应用实例

  • p106 等待超时模式
  • p106 一个简单的数据库连接池示例
  • p110 线程池技术及其示例
  • p114 一个基于线程池技术的简单Web服务器

第五章 Java中的锁

5.1 Lock接口

  • p120 Lock的使用方式
  • p120 Lock提供的synchoronized没有的特征(非阻塞获取锁、被中断地获取锁、超时获取锁)
  • p120 Lock的API

5.2 队列同步器

  • p121 队列同步器AbstractQueuedSynchronizer
  • p121 同步器提供的三个基本方法 — getState()、setState()和compareAndSetState()
  • p121 锁和同步器的关系
  • p121 队列同步器的接口与示例
  • p121 同步器可重写的方法
  • p122 同步器提供的模板方法
  • p122 独占锁
  • p124 队列同步器的实现分析
  • p124 同步队列
  • p124 同步队列中的节点,及其属性类型与名称及描述
  • p125 同步队列的基本结构
  • p126 独占式同步状态获取与释放
  • p128 独占式同步状态获取流程
  • p129 共享式同步状态获取与释放
  • p131 独占式超时获取同步状态
  • p133 自定义同步组件 - TwinsLock
  • p134 自定义同步器定义为自定义同步组件的内部类

5.3 重入锁

  • p136 重入锁ReentrantLock
  • p136 锁获取的公平性问题
  • p136 重进入的实现
  • p137 公平与非公平获取锁的区别

5.4 读写锁

  • p140 读写锁
  • p141 读写锁的接口与示例
  • p141 ReentrantReadWriteLock
  • p142 读写锁的实现分析
  • p142 一个整型变量上维护多种状态 - 按位切割使用
  • P145 锁降级

5.5 LockSupport工具

  • p146 LockSupport提供的阻塞和唤醒方法
  • p147 阻塞对象Blocker在LockSupport中的作用(由dump体现)

5.6 Condition接口

  • p147 Object的监视器方法与Condition接口的对比
  • p148 Condition接口与示例
  • p148 调用Condition的方法前应该先获取锁
  • p148 Condition的部分方法以及描述
  • p149 有界队列
  • p150 Condition的实现分析
  • p151 await和signal的实质

第六章 Java并发容器和框架

6.1 ConcurrentHashMap的实现原理与使用

  • p155 为什么要使用ConcurrentHashMap
  • p156 锁分段技术
  • p156 ConcurrentHashMap的结构
  • p157 ConcurrentHashMap的初始化
  • p159 在分段锁中定位Segment
  • P160 ConcurrentHashMap的操作(get、put、size)
  • p160 ConcurrentHashMap的get方法里将共享变量定义为volatile

6.2 ConcurrentLinkedQueue

  • p161 实现线程安全的队列的方法
  • p162 ConcurrentLinkedQueue的结构
  • p162 入队列
  • p165 HOPS的设计意图
  • p163 出队列

6.3 Java中的阻塞队列

  • p167 什么是阻塞队列
  • p167 阻塞队列不可用时由不同方法提供的四种处理方式
  • p168 JDK7提供的7个阻塞队列
  • P168 队列ArrayBlockingQueue - 数组结构组成的有界阻塞队列
  • p169 队列LinkedBlockingQueue - 链表实现的(伪)有界阻塞队列
  • p169 队列PriorityBlockingQueue - 支持优先级的有界阻塞队列
  • p169 队列DelayQueue - 支持延时获取元素的无界等待队列
  • p171 队列SynchronousQueue - 不存储元素的阻塞队列
  • p171 队列LinkedTransferQueue - 由链表结构组成的无界阻塞队列
  • p172 队列LinkedBlockingDeque - 链表结构组成的双向阻塞队列
  • p172 阻塞队列的实现原理
  • p174 native方法unsafe.park
  • p174 JVM实现park方法

6.4 Fork/Join框架

  • p175 什么是Fork/Join框架
  • p176 工作窃取算法
  • p177 Fork/Join框架的设计
  • p177 RecursiveAction和RecursiveTask
  • p177 使用Fork/Join框架
  • p179 Fork/Join框架的异常处理
  • p179 Fork/Join框架的实现原理

第七章 Java中的12个原子操作类

  • p182 Atomic包

7.1 原子更新基本类型类

  • p182 三种原子更新基本类型类(Boolean、Integer、Long)
  • p184 如何原子更新其他的基本类型

7.2 原子更新数组

  • p184 三种原子更新数组(Integer、Long、Reference)
  • p185 AtomicIntegerArray对内部元素修改时,不影响构造时传入的数组

7.3 原子更新引用类型

  • p185 三种原子更新引用类型(Reference、ReferenceFieldUpdater、MarkableReference)

7.4 原子更新字段类

  • P187 三种原子更新字段类(IntegerFieldUpdater、LongFieldUpdater、StampedReference)

第八章 Java中的并发工具类

8.1 等待多线程完成的CountDownLatch

  • p189 CountDownLatch允许一个或多个线程等待其他线程完成操作
  • p190 join方法

8.2 同步屏障CyclicBarrier

  • p191 让一组线程达到后被阻塞的可循环使用屏障CyclicBarrier
  • p191 CyclicBarrier简介(使用方式)
  • p193 CyclicBarrier的应用场景
  • p195 CyclicBarrier和CountDownLatch的区别
  • p195 CyclicBarrier的其他有用的方法(reset、isBroken、getNumberWaiting)

8.3 控制并发线程数的Semaphore

  • P196 信号量Semaphore
  • p196 Semaphore的应用场景
  • p197 Semaphore的其他方法

8.4 线程间交换数据的Exchanger

  • p198 交换者Exchanger

第九章 Java中的线程池

  • p200 线程池带来的三个好处

9.1 线程池的实现原理

  • p200 线程池的处理流程
  • p201 ThreadPoolExecutor执行execute方法的四种情况

9.2 线程池的使用

  • p203 线程池的创建和构造参数介绍
  • p204 四种队列和线程池都满了时的饱和策略
  • p205 向线程池提交任务
  • p205 关闭线程池
  • p206 合理配置线程池
  • p206 线程池的监控

第十章 Executor框架

  • p208 Java线程的执行机制由Executor框架提供

10.1 Executor框架的两级调度模型

  • p208 Executor的两级调度模型
  • p208 Executor框架的结构与成员
  • p209 Executor框架的结构
  • p210 Executor框架的类与接口示意图
  • p210 Executor框架的使用示意图
  • p210 Executor框架使用流程
  • p211 Executor框架的成员
  • p211 ThreadPoolExecutor介绍(FixedThreadPool、SingleThreadExecutor、CachedThreadPool)
  • p211 ScheduledThreadPoolExecutor介绍(ScheduledThreadPoolExecutor、SingleThreadScheduledExecutor)
  • p212 Future接口
  • p212 Runnable接口和Callable接口
  • p212 把Runnable对象包装为Callable对象

10.2 ThreadPoolExecutor详解

  • p213 FixedThreadPool详解
  • p214 使用无界队列作为工作队列对线程池产生的影响
  • p214 SingleThreadExecutor详解
  • p215 CachedThreadPool详解

10.3 ScheduledThreadPoolExecutor详解

  • p217 ScheduledThreadPoolExecutor的运行机制
  • p217 ScheduledThreadPoolExecutor的执行
  • p218 ScheduledThreadPoolExecutor相比ThreadPoolExecutor做的三个修改
  • p218 ScheduledThreadPoolExecutor的实现
  • p218 ScheduledFutureTask的三个成员变量(time、sequenceNumber、period)
  • p218 ScheduledThreadPoolExecutor中线程执行任务的步骤
  • P220 DelayQueue获取任务的三大步骤
  • P221 DelayQueue添加任务的三大步骤

10.4 FutureTask详解

  • p222 FutureTask简介
  • p222 FutureTask的三种状态
  • p222 FutureTask的使用
  • p224 FutureTask的实现
  • p227 级联唤醒
posted @ 2021-12-25 21:39  pedro7  阅读(148)  评论(0编辑  收藏  举报