Java高併發核心程式設計.卷2,多執行緒、鎖、JMM、JUC、高併發設計模式

# 《Java高併發核心程式設計。卷2,多執行緒、鎖、JMM、JUC、高併發設計模式》

## 目錄

Java高併發核心程式設計.卷2,多執行緒、鎖、JMM、JUC、高併發設計模式

## 第1章 多執行緒原理與實戰

### 1。2無處不在的程序和執行緒

- 1。2。1程序的基本原理

- 1。2。2執行緒的基本原理

- 1。2。3程序與執行緒的區別

### 1。3建立執行緒的4種方法

- 1。3。1Thread類詳解

- 1。3。2建立一個空執行緒

- 1。3。3執行緒建立方法一:繼承Thread類建立執行緒類

- 1。3。4執行緒建立方法二:實現Runnable介面建立執行緒目標類

- 1。3。5優雅建立Runnable執行緒目標類的兩種方式

- 1。3。6透過實現Runnable介面的方式建立執行緒目標類的優缺點

- 1。3。7執行緒建立方法三:使用Callable和FutureTask建立執行緒

- 1。3。8執行緒建立方法四:透過執行緒池建立執行緒

### 1。4執行緒的核心原理

- 1。4。1執行緒的排程與時間片

- 1。4。2執行緒的優先順序

- 1。4。3執行緒的生命週期

- 1。4。4一個執行緒狀態的簡單演示案例

- 1。4。5使用Jstack工具檢視執行緒狀態

### 1。5執行緒的基本操作

- 1。5。1執行緒名稱的設定和獲取

- 1。5。2執行緒的sleep操作

- 1。5。3執行緒的interrupt操作

- 1。5。4執行緒的join操作

- 1。5。5執行緒的yield操作

- 1。5。6執行緒的daemon操作

- 1。5。7執行緒狀態總結

### 1。6執行緒池原理與實戰

- 1。6。1 JUC的執行緒池架構

- 1。6。2 Executors的4種快捷建立執行緒池的方法

- 1。6。3執行緒池的標準建立方式

- 1。6。4向執行緒池提交任務的兩種方式

- 1。6。5執行緒池的任務排程流程

- 1。6。6 ThreadFactory (執行緒工廠)

- 1。6。7任務阻塞佇列

- 1。6。8排程器的鉤子方法

- 1。6。9執行緒池的拒絕策略

- 1。6。10執行緒池的優雅關閉

- 1。6。11 Executors快捷建立執行緒池的潛在問題

### 1。7確定執行緒池的執行緒數

## 第2章 Java內建鎖的核心原理

### 2。1執行緒安全問題

- 2。1。1 自增運算不是執行緒安全的

- 2。1。2臨界區資源與臨界區程式碼段

### 2。2 synchronized關鍵字

- 2。2。1 synchronized同步方法

- 2。2。2 synchronized同步塊

- 2。2。3靜態的同步方法

### 2。3生產者-消費者問題

- 2。3。1生產者-消費者模式

- 2。3。2一個執行緒不安全的實現版本

- 2。3。3一個執行緒安全的實現版本

### 2。4 Java物件結構與內建鎖

- 2。4。1 Java物件結構

- 2。4。2 Mark Word的結構資訊

- 2。4。3使用JOLI具檢視物件的佈局

- 2。4。4大小端問題

- 2。4。5無鎖、偏向鎖、輕量級鎖和重量級鎖

### 2。5偏向鎖的原理與實戰

- 2。5。1偏向鎖的核心原理

- 2。5。2偏向鎖的演示案例

- 2。5。3偏向鎖的膨脹和撤銷

### 2。6輕量級鎖的原理與實戰

- 2。6。1輕量級鎖的核心原理

- 2。6。2輕量級鎖的演示案例

- 2。6。3輕量級鎖的分類

- 2。6。4輕量級鎖的膨脹

### 2。7重量級鎖的原理與實戰

- 2。7。1重量級鎖的核心原理

- 2。7。2重量級鎖的開銷

- 2。7。3重量級鎖的演示案例

### 2。8偏向鎖、輕量級鎖與重量級鎖的對比

### 2。9執行緒間通訊

- 2。9。1執行緒間通訊的定義

- 2。9。2低效的執行緒輪詢

- 2。9。3 wait方法和notify方法的原理

- 2。9。4“等待通知’ 通訊模式演示案例

- 2。9。5生產者-消費者之間的執行緒間通訊

- 2。9。6需要在synchronized同步塊的內部使用wait和notify

## 第3章 CAS原理與JUC原子類

### 3。1 什麼是CAS

- 3。1。1 Unsafe類中的CAS方法

- 3。1。2使用CAS進行無鎖程式設計

- 3。1。3使用無鎖程式設計實現輕量級安全自增

- 3。1。4欄位偏移量的計算

### 3。2 JUC原子類

- 3。2。1 JUC中的Atomic原子操作包

- 3。2。2基礎原子類AtomicInteger

- 3。2。3陣列原子類AtomicIntegerArray

- 3。2。4 AtomicInteger執行緒安全原理,

### 3。3物件操作的原子性

- 3。3。1引用型別原子類

- 3。3。2屬性更新原子類

### 3。4 ABA問題

- 3。4。1瞭解ABA問題

- 3。4。2 ABA問題解決方案

- 3。4。3使用AtomicStampedReference解決ABA問題

- 3。4。4使用AtomicMarkableReference解決ABA問題

### 3。5提升高併發場景下CAS操作的效能

- 3。5。1以空間換時間: LongAdder

- 3。5。2 LongAdder的原理

### 3。6 CAS在JDK中的廣泛應用

- 3。6。1 CAS操作的弊端和規避措施

-3。6。2 CAS操作在JDK中的應用

## 第4章 可見性與有序性的原理

### 4。1 CPU物理快取結構

### 4。2併發程式設計的三大問題

- 4。2。1原子性問題

- 4。2。2可見性問題

- 4。2。3有序性問題

### 4。3硬體層的MESI協議原理

- 4。3。1匯流排鎖和快取鎖

- 4。3。2 MSI協議

- 4。3。3 MES|協議及RFO請求

- 4。3。4 volatile的原理

### 4。4有序性與記憶體屏障

- 4。4。1重排序

- 4。4。2 As-if- -Serial規則

- 4。4。3硬體層面的記憶體屏障

### 4。5 JMM詳解

- 4。5。1什麼是Java記憶體模型

- 4。5。2 JMM與JVM物理記憶體的區別

- 4。5。3 JMM的8個操作

- 4。5。4 JMM如何解決有序性問題

- 4。5。5 volatile語義中的記憶體屏障

### 4。6 Happens- Before規則

- 4。6。1 Happens- -Before規則介紹

- 4。6。2規則1:順序性規則

- 4。6。3規則2: volatile規則

- 4。6。4規則3:傳遞性規則

- 4。6。5規則4:監視鎖規則。

- 4。6。6規則5: start()規則

- 4。6。7規則6: join()規則

### 4。7 volatile不具備原子性

- 4。7。1 volatile變數的自增例項

- 4。7。2 volatile變數的複合操作不具備原子性的原理

## 第5章 JUC顯式鎖的原理與實戰

### 5。1顯式鎖

- 5。1。1顯式鎖L _ock介面

- 5。1。2可重入鎖ReentrantL ock

- 5。1。3使用顯式鎖的模板程式碼

- 5。1。4基於顯式鎖進行“等待通知”方式的執行緒間通訊

- 5。1。5 L ockSupport

- 5。1。6顯式鎖的分類

### 5。2悲觀鎖和樂觀鎖

- 5。2。1悲觀鎖存在的問題

- 5。2。2透過CAS實現樂觀鎖

- 5。2。3不可重入的自旋鎖

- 5。2。4可重入的自旋鎖。

- 5。2。5 CAS可能導致“匯流排風暴’

- 5。2。6 CLH自旋鎖

### 5。3公平鎖與非公平鎖

- 5。3。1非公平鎖實戰

- 5。3。2公平鎖實戰

### 5。4可中斷鎖與不可中斷鎖

- 5。4。1鎖的可中斷搶佔

- 5。4。2死鎖的監測與中斷

### 5。5共享鎖與獨佔鎖

- 5。5。1獨佔鎖

- 5。5。2共享鎖Semaphore

- 5。5。3共享鎖CountDownL 。atch

### 5。6讀寫鎖

- 5。6。1讀寫鎖ReentrantReadWriteL ock

- 5。6。2鎖的升級與降級

- 5。6。3 StampedL ock

## 第6章 AQS抽象同步器的核心原理

### 6。1鎖與佇列的關係

### 6。2 AQS的核心成員

- 6。2。1狀態標誌位

- 6。2。2佇列節點類

- 6。2。3 FIFO雙向同步佇列

- 6。2。4 JUC顯式鎖與AQS的關係

- 6。2。5 ReentrantL ock與AQS的組合關係

### 6。3 AQS中的模板模式

- 6。3。1模板模式

- 6。3。2一個模板模式的參考實現

- 6。3。3 AQS的模板流程,

- 6。3。4 AQS中的鉤子方法

### 6。4透過AQS實現一把簡單的獨佔鎖

- 6。4。1簡單的獨佔鎖的UML類圖

- 6。4。2簡單的獨佔鎖的實現

- 6。4。3 SimpleMockL ock測試用例

### 6。5 AQS鎖搶佔的原理

- 6。5。1顯式鎖搶佔的總體流程

- 6。5。2 AQS模板方法: acquire(arg)

- 6。5。3鉤子實現: tryAcquire(arg)

- 6。5。4直接入隊: addWaiter

- 6。5。5 自旋入隊: enq

- 6。5。6自旋搶佔: acquireQueued()

- 6。5。7掛起預判: shouldParkAfterFailedAcquire()

- 6。5。8執行緒掛起: parkAndCheckInterrupt()

### 6。6 AQS的兩個關鍵點:節點的入隊和出隊

- 6。6。1節點的自旋入隊

- 6。6。2節點的出隊

### 6。7 AQS鎖釋放的原理

- 6。7。1 SimpleMockL _ock獨佔鎖的釋放流程

- 6。7。2 AQS模板方法: release()

- 6。7。3鉤子實現: tryRelease()

- 6。7。4喚醒後繼: unparkSuccessor()

### 6。8 ReentrantL ock的搶鎖流程

- 6。8。1 ReentrantL ock非公平鎖的搶佔流程

- 6。8。2非公平鎖的同步器子類

- 6。8。3非公平搶佔的鉤子方法: tryAcquire(arg)

- 6。8。4 ReentrantL ock公平鎖的搶佔流程

- 6。8。5公平鎖的同步器子類

- 6。8。6公平搶佔的鉤子方法: tryAcquire(arg)

- 6。8。7是否有後繼節點的判斷

### 6。9 AQS條件佇列

- 6。9。1 Condition基本原理

- 6。9。2 await()等待方法原理

- 6。9。3 signal()喚醒方法原理,

### 6。10 AQS的實際應用

## 第7章 JUC容器類

### 7。1執行緒安全的同步容器類

### 7。2 JUC高併發容器

### 7。3 CopyOnWriteArrayList

- 7。3。1 CopyOnWriteArrayList的使用

- 7。3。2 CopyOnWriteArrayList的原理

- 7。3。3 CopyOnWriteArrayL ist讀取操作

- 7。3。4 CopyOnWriteArrayList寫入操作

- 7。3。5 CopyOnWriteArrayList的迭代器實現

### 7。4 BlockingQueue

- 7。4。1 BlockingQueue的特點

- 7。4。2阻塞佇列的常用方法

- 7。4。3常見的BlockingQueue

- 7。4。4 ArrayBlockingQueue的基本使用

- 7。 4。5 ArrayBlockingQueue構造器和成員

- 7。4。6非阻塞式新增元素: add()、 offer()方 法的原理

- 7。4。7阻塞式新增元素: put()方 法的原理

- 7。4。8非阻塞式刪除元素: pol()方法的原理

- 7。4。9阻塞式刪除元素: take()方 法的原理

- 7。4。10 peek()直接返回當前佇列的頭元素

### 7。5 ConcurrentHashMap

- 7。5。1 HashMap和HashTable的問題

- 7。5。2 JDK 1。7版本ConcurrentHashMap的結構

- 7。5。3 JDK 1。7版本ConcurrentHashMap的核心原理

- 7。5。4 JDK 1。8版本ConcurrentHashMap的結構

- 7。5。5 JDK 1。8版本ConcurrentHashMap的核心原理

- 7。5。6 JDK 1。8版本ConcurrentHashMap的核心原始碼

## 第8章 高併發設計模式

### 8。1執行緒安全的單例模式

- 8。1。1從餓漢式單例到懶漢式單例

- 8。1。2使用內建鎖保護懶漢式單例

- 8。1。3雙重檢查鎖單例模式

- 8。1。4使用雙重檢查鎖+volatile

- 8。1。5使用靜態內部類實現懶漢式單例模式

### 8。2 Master-Worker模式

- 8。2。3 Nginx中Master- Worker模 式的實現

- 8。2。2 Netty中Master- -Worker模式的實現

- 8。2。1 Master-Worker模式的參考實現

### 8。3 ForkJoin模式

- 8。3。1 ForkJoin模式的原理

- 8。3。2 ForkJoin框架

- 8。3。3 ForkJoin框架使用實戰

- 8。3。4 ForkJoin框架的核心API

- 8。3。5工作竊取演算法

- 8。3。6 ForkJoin框 架的原理

### 8。4生產者-消費者模式

### 8。5 Future模式

## 第9章 高併發核心模式之非同步回撥模式

### 9。1從泡茶的案例講起

### 9。2 join:非同步阻塞之悶葫蘆

- 9。2。1執行緒的合併流程

- 9。2。2呼叫join()實現非同步泡茶喝

- 9。2。3 join()方法詳解;

### 9。3 FutureTask:非同步呼叫之重武器

- 9。3。1透過Future Task獲取非同步執行結果的步驟

- 9。3。2使用FutureTask實現非同步泡茶喝

### 9。4非同步回撥與主動呼叫

### 9。5 Guava的非同步回撥模式

- 9。5。1詳解FutureCallback

- 9。5。2詳解L istenableFuture

- 9。5。3 ListenableFuture非同步任務

- 9。5。4使用Guava實現泡茶喝的例項

- 9。5。5 Guava非同步回撥和Java非同步呼叫的區別

### 9。6 Netty的非同步回撥模式

- 9。6。1 GenericFuturel istener介面詳解

- 9。6。2 Netty的Future介面詳解

- 9。6。3 ChannelFuture的使用

- 9。6。4 Netty的出站和入站非同步回撥

### 9。7非同步回撥模式小結

## 第10章 CompletableFuture非同步回撥

### 10。1 CompletableFuture詳解

- 10。1。1 CompletableFuture的UML類關係

- 10。1。2 CompletionStage介面

- 10。1。3使用runAsync和supplyAsync建立子任務

- 10。1。4設定子任務回撥鉤子

- 10。1。5呼叫handle()方法統- -處理異常和結果

- 10。1。6執行緒池的使用

### 10。2非同步任務的序列執行

- 10。2。1 thenApply()方法

- 10。2。2 thenRun()方法

- 10。2。3 thenAccept()方法

- 10。2。 4 thenCompose()方法

- 10。2。5 4個任務序列方法的區別

### 10。3非同步任務的合併執行

- 10。3。1 thenCombine()方法

- 10。3。2 runAfterBoth()方法

- 10。3。3 thenAcceptBoth()方法

- 10。3。4 allOf()等待所有的任務結束

### 10。4非同步任務的選擇執行

- 10。4。1 applyToEither()方法

- 10。4。2 runAfterEither()方法

- 10。4。3 acceptEither()方法

### 10。5 CompletableFuture的綜合案例

- 10。5。1 1EFCompletableFuture實現泡茶喝例項

- 10。5。2 15 FCompletableFuture進行多個RPC呼叫

- 10。5。3使用RxJava模擬RPC非同步回撥

## 參考資料

- 《Java高併發核心程式設計。卷2,多執行緒、鎖、JMM、JUC、高併發設計模式》