描述
內容簡介
\\好評再版//
☆先了解作業系統中的執行緒排程架構 ☆多核心CPU上設計Java平行程式 ☆併發式程式的設計理念,分工、同步、互斥 ☆核心原理說明,原子性、可見性、有序性 Synchronized、AQS、CAS、鎖、執行緒池、ThreadLocal的核心原理 ☆手動開發執行緒池實戰案例 ☆使用CAS開發自旋鎖實戰案例 ☆使用讀/寫鎖實戰快取 ☆使用AQS實現可重入鎖 ☆開發分散式鎖架構 ☆完整大型實戰一個秒殺系統的完整架構
【內容簡介】 高併發是高流量、高資料量服務線上系統架構必須具備的特性,如果想從微觀核心到併發應用,再到業務架構學習高併發的核心原理,以及高併發系統的工程架構最佳實踐,本書是中文書籍中最佳的範本,在細節部分,對核心排程、同步非同步、各類鎖的實現細節都有詳盡的敘述,另外在在併發應用層面,對CAS問題、ABA問題、連接池實現,也有很完整的案例講解。在更高的架構層面上,對快取併發實戰、電子商務超賣問題、秒殺系統架構,更有清楚且應用上的說明,讓讀者能從CPU、作業系統、JVM底層原理為基礎,站在實踐的角度上全面了解高併發的基本原理及實用。在電腦多核心時代,併發程式設計是每個程式設計師都應掌握的技能,伺服器上的CPU核心在EPYC出後,成千上百個處理器同時為你工作,如果你寫出來的程式還無法執行多處理程序,多執行緒,多核心,小心真的成為時代的眼淚! |
作者簡介
|
目錄
第1篇 基礎知識
01 作業系統執行緒排程 ▌1.1 馮· 諾依曼系統結構 1.1.1 概述 1.1.2 電腦五大組成部分 ▌1.2 CPU 架構 1.2.1 CPU 的組成部分 1.2.2 CPU 邏輯結構 1.2.3 單核心CPU 的不足 1.2.4 多核心CPU 架構 1.2.5 多CPU 架構 ▌1.3 作業系統執行緒 1.3.1 使用者級執行緒 1.3.2 核心級執行緒 1.3.3 混合級執行緒 ▌1.4 Java 執行緒與作業系統執行緒的關係 ▌1.5 本章複習
02 並行程式設計概述 ▌2.1 並行程式設計的基本概念 2.1.1 程式 2.1.2 處理程序與執行緒 2.1.3 執行緒組 2.1.4 使用者執行緒與守護執行緒 2.1.5 並行與並行 2.1.6 同步與非同步 2.1.7 共享與獨享 2.1.8 臨界區 2.1.9 阻塞與非阻塞 ▌2.2 並行程式設計的風險 2.2.1 安全性問題 2.2.2 活躍性問題 2.2.3 性能問題 ▌2.3 並行程式設計中的鎖 2.3.1 悲觀鎖與樂觀鎖 2.3.2 公平鎖與非公平鎖 2.3.3 獨佔鎖與共享鎖 2.3.4 可重入鎖與不可重入鎖 2.3.5 可中斷鎖與不可中斷鎖 2.3.6 讀/ 寫鎖 2.3.7 自旋鎖 2.3.8 鎖死、饑餓與活鎖 ▌2.4 本章複習
第2篇 核心原理 03 並行程式設計的三大核心問題 ▌3.1 分工問題 3.1.1 模擬現實案例 3.1.2 並行程式設計中的分工 ▌3.2 同步問題 3.2.1 模擬現實案例 3.2.2 並行程式設計中的同步 ▌3.3 互斥問題 3.3.1 模擬現實案例 3.3.2 並行程式設計中的互斥 ▌3.4 本章複習
04 並行程式設計的本質問題 ▌4.1 電腦的核心矛盾 4.1.1 核心矛盾概述 4.1.2 CPU 如何解決核心矛盾 4.1.3 作業系統如何解決核心矛盾 4.1.4 編譯器如何解決核心矛盾 4.1.5 引發的問題 ▌4.2 原子性 4.2.1 原子性概述 4.2.2 原子性問題 4.2.3 Java 中的原子性問題 4.2.4 原子性問題複習 ▌4.3 可見性 4.3.1 可見性概述 4.3.2 可見性問題 4.3.3 Java 中的可見性問題 4.3.4 可見性問題複習 ▌4.4 有序性 4.4.1 有序性概述 4.4.2 有序性問題 4.4.3 Java 中的有序性問題 4.4.4 有序性問題複習 ▌4.5 解決方案 4.5.1 原子性問題解決方案 4.5.2 可見性與有序性問題解決方案 ▌4.6 本章複習
05 原子性的核心原理 ▌5.1 原子性原理 ▌5.2 處理器保證原子性 5.2.1 CPU 保證基本記憶體操作的原子性 5.2.2 匯流排鎖保證原子性 5.2.3 快取鎖保證原子性 ▌5.3 互斥鎖保證原子性 5.3.1 互斥鎖模型 5.3.2 最佳化後的互斥鎖模型 ▌5.4 CAS 保證原子性 ▌5.5 本章複習
06 可見性與有序性核心原理 ▌6.1 CPU 多級快取架構 6.1.1 CPU 為何使用多級快取架構 6.1.2 CPU 多級快取架構原理 6.1.3 CPU 的計算流程 ▌6.2 快取一致性 6.2.1 什麼是快取一致性 6.2.2 快取一致性協定 6.2.3 MESI 協定快取狀態 6.2.4 MESI 協定的狀態轉換 6.2.5 MESI 協定帶來的問題 ▌6.3 錯誤分享 6.3.1 錯誤分享的概念 6.3.2 錯誤分享產生的場景 6.3.3 如何解決錯誤分享問題 ▌6.4 volatile 核心原理 6.4.1 保證可見性核心原理 6.4.2 保證有序性核心原理 6.4.3 volatile 的局限性 ▌6.5 記憶體屏障 6.5.1 編譯器重排序 6.5.2 CPU 重排序 6.5.3 as-if-serial 原則 6.5.4 電腦硬體實現的記憶體屏障 ▌6.6 Java 記憶體模型 6.6.1 Java 記憶體模型的概念 6.6.2 Java 記憶體模型的八大操作 6.6.3 Java 記憶體模型解決可見性與有序性問題 ▌6.7 Happens-Before 原則 6.7.1 Happens-Before 原則概述 6.7.2 程式次序原則 6.7.3 volatile 變數原則 6.7.4 傳遞原則 6.7.5 鎖定原則 6.7.6 執行緒啟動原則 6.7.7 執行緒終結原則 6.7.8 執行緒中斷原則 6.7.9 物件終結原則 ▌6.8 本章複習
07 synchronized 核心原理 ▌7.1 synchronized 用法 7.1.1 同步實例方法 7.1.2 同步靜態方法 7.1.3 同步程式區塊 ▌7.2 Java 物件結構 7.2.1 物件結構總覽 7.2.2 物件標頭 7.2.3 實例資料 7.2.4 對齊填充 ▌7.3 Java 物件標頭 7.3.1 Mark Word 7.3.2 類型指標 7.3.3 陣列長度 ▌7.4 使用JOL 查看物件資訊 7.4.1 引入JOL 環境依賴 7.4.2 列印物件資訊 7.4.3 列印物件鎖狀態 ▌7.5 synchronized 核心原理 7.5.1 synchronized 底層原理 7.5.2 Monitor 鎖原理 7.5.3 反編譯synchronized方法 7.5.4 反編譯synchronized程式區塊 ▌7.6 偏向鎖 7.6.1 偏向鎖核心原理 7.6.2 偏向鎖的撤銷 7.6.3 偏向鎖案例 ▌7.7 輕量級鎖 7.7.1 輕量級鎖核心原理 7.7.2 輕量級鎖案例 ▌7.8 重量級鎖 7.8.1 重量級鎖核心原理 7.8.2 重量級鎖案例 ▌7.9 鎖升級的過程 ▌7.10 鎖消除 ▌7.11 本章複習
08 AQS 核心原理 ▌8.1 AQS 核心資料結構 8.1.1 AQS 資料結構原理 8.1.2 AQS 內部佇列模式 ▌8.2 AQS 底層鎖的支援 8.2.1 核心狀態位元 8.2.2 核心節點類別 8.2.3 獨佔鎖模式 8.2.4 共享鎖模式 ▌8.3 本章複習
09 Lock 鎖核心原理 ▌9.1 顯示鎖 ▌9.2 公平鎖與非公平鎖 9.2.1 公平鎖原理 9.2.2 ReentrantLock 中的公平鎖 9.2.3 公平鎖實戰 9.2.4 非公平鎖原理 9.2.5 ReentrantLock 中的非公平鎖 9.2.6 非公平鎖實戰 ▌9.3 悲觀鎖與樂觀鎖 9.3.1 悲觀鎖原理 9.3.2 悲觀鎖實戰 9.3.3 樂觀鎖原理 9.3.4 樂觀鎖實戰 ▌9.4 可中斷鎖與不可中斷鎖 9.4.1 可中斷鎖原理 9.4.2 可中斷鎖實戰 9.4.3 不可中斷鎖原理 9.4.4 不可中斷鎖實戰 ▌9.5 排他鎖與共享鎖 9.5.1 排他鎖原理 9.5.2 排他鎖實戰 9.5.3 共享鎖原理 9.5.4 共享鎖實戰 ▌9.6 可重入鎖 9.6.1 可重入鎖原理 9.6.2 可重入鎖實戰 ▌9.7 讀/ 寫鎖 9.7.1 讀/ 寫鎖原理 9.7.2 ReadWriteLock 讀/寫鎖 9.7.3 ReadWriteLock 鎖降級 9.7.4 StampedLock 讀/寫鎖 9.7.5 StampedLock 鎖的升級與降級 9.7.6 讀/ 寫鎖實戰 ▌9.8 LockSupport 9.8.1 LockSupport 原理 9.8.2 LockSupport 實戰 ▌9.9 本章複習
10 CAS 核心原理 ▌10.1 CAS 的基本概念 ▌10.2 CAS 的核心類別Unsafe 10.2.1 Unsafe 類別的核心方法 10.2.2 Unsafe 類別實戰 ▌10.3 使用CAS 實現count++ 10.3.1 案例分析 10.3.2 程式實現 10.3.3 測試程式 ▌10.4 ABA 問題 10.4.1 ABA 問題概述 10.4.2 ABA 問題解決方案 10.4.3 Java 如何解決ABA問題 ▌10.5 本章複習
11 鎖死的核心原理 ▌11.1 鎖死的基本概念 ▌11.2 鎖死的分析 11.2.1 執行緒不安全 11.2.2 串列執行 11.2.3 發生鎖死 ▌11.3 形成鎖死的必要條件 ▌11.4 鎖死的預防 ▌11.5 本章複習
12 鎖最佳化 ▌12.1 縮小鎖的範圍 ▌12.2 減小鎖的細微性 ▌12.3 鎖分離 ▌12.4 鎖分段 ▌12.5 鎖粗化 ▌12.6 避免熱點區域問題 ▌12.7 獨佔鎖的替換方案 ▌12.8 其他最佳化方案 ▌12.9 本章複習
13 執行緒池核心原理 ▌13.1 執行緒池的核心狀態 13.1.1 核心狀態說明 13.1.2 核心狀態的流轉過程 ▌13.2 執行緒池的建立方式 13.2.1 透過Executors 類別建立執行緒池 13.2.2 透過ThreadPoolExecutor類別建立執行緒池 13.2.3 透過ForkJoinPool類別建立執行緒池 13.2.4 透過ScheduledThreadPoolExecutor 類別建立執行緒池 ▌13.3 執行緒池執行任務的核心流程 13.3.1 執行任務的流程 13.3.2 拒絕策略 ▌13.4 執行緒池的關閉方式 13.4.1 shutdown() 方法 13.4.2 shutdownNow() 方法 ▌13.5 如何確定最佳執行緒數 13.5.1 CPU 密集型程式 13.5.2 I/O 密集型程式 ▌13.6 本章複習
14 ThreadLocal 核心原理 ▌14.1 ThreadLocal 的基本概念 ▌14.2 ThreadLocal 的使用案例 ▌14.3 ThreadLocal 的核心原理 14.3.1 Thread 類別原始程式 14.3.2 set() 方法 14.3.3 get() 方法 14.3.4 remove() 方法 ▌14.4 ThreadLocal 變數的不繼承性 ▌14.5 InheritableThreadLocal 的使用案例 ▌14.6 InheritableThreadLocal 的核心原理 ▌14.7 本章複習
第3篇 實戰案例 15 手動開發執行緒池實戰 ▌15.1 案例概述 ▌15.2 專案架設 ▌15.3 核心類別實現 15.3.1 定義核心欄位 15.3.2 建立內部類別WorkThread 15.3.3 建立執行緒池的建構方法 15.3.4 建立執行任務的方法 15.3.5 建立關閉執行緒池的方法 15.3.6 完整原始程式碼範例 ▌15.4 測試程式 ▌15.5 本章複習
16 基於CAS 實現自旋鎖實戰 ▌16.1 案例概述 ▌16.2 專案架設 ▌16.3 核心類別實現 16.3.1 CasLock 介面實現 16.3.2 MyCasLock 類別實現 ▌16.4 測試程式 ▌16.5 本章複習
17 基於讀/ 寫鎖實現快取實戰 ▌17.1 案例概述 ▌17.2 專案架設 ▌17.3 核心類別實現 17.3.1 ReadWriteCache<K, V>核心介面的實現 17.3.2 ConcurrentReadWriteCache<K, V> 核心類別的實現 ▌17.4 測試程式 ▌17.5 本章複習
18 基於AQS 實現可重入鎖實戰 ▌18.1 案例概述 ▌18.2 專案架設 ▌18.3 核心類別實現 18.3.1 AQSSync 內部類別的實現 18.3.2 ReentrantAQSLock 核心類別的實現 18.3.3 完整原始程式碼 ▌18.4 測試程式 ▌18.5 本章複習
第4篇 系統架構 19 深度解密分散式鎖架構 ▌19.1 鎖解決的本質問題 ▌19.2 電子商務超賣問題 19.2.1 超賣問題概述 19.2.2 超賣問題案例 ▌19.3 JVM 提供的鎖 19.3.1 JVM 鎖的原理 19.3.2 JVM 鎖的不足 ▌19.4 分散式鎖 19.4.1 分散式鎖的實現方法 19.4.2 分散式鎖的基本要求 ▌19.5 CAP 理論與分散式鎖模型 19.5.1 CAP 理論 19.5.2 基於Redis 的AP 架構模型 19.5.3 基於Zookeeper 的CP架構模型 19.5.4 AP 架構模型的問題與解決方案 ▌19.6 基於Redis 實現分散式鎖 19.6.1 Redis 命令分析 19.6.2 引入分散式鎖 19.6.3 引入try-finally 程式區塊 19.6.4 引入Redis 逾時機制 19.6.5 加鎖操作原子化 19.6.6 誤刪鎖分析 19.6.7 實現加鎖和解鎖歸一化 19.6.8 可重入性分析 19.6.9 解決可重入性問題 19.6.10 實現鎖的阻塞性 19.6.11 解決鎖故障問題 19.6.12 解鎖操作原子化 ▌19.7 本章複習
20 深度解密秒殺系統架構 ▌20.1 電子商務系統架構 ▌20.2 秒殺系統的特點 20.2.1 秒殺系統的業務特點 20.2.2 秒殺系統的技術特點 ▌20.3 秒殺系統的方案 20.3.1 秒殺系統的三個階段 20.3.2 秒殺系統的性能最佳化 ▌20.4 秒殺系統設計 20.4.1 同步下單流程 20.4.2 非同步下單流程 ▌20.5 扣減庫存設計 20.5.1 下單減庫存 20.5.2 付款減庫存 20.5.3 預扣減庫存 20.5.4 扣減庫存問題的解決方案 20.5.5 秒殺系統扣減庫存方案 ▌20.6 Redis 助力秒殺系統 20.6.1 Redis 實現扣減庫存 20.6.2 完美解決超賣問題 20.6.3 Redis 分割庫存 20.6.4 快取穿透技術 ▌20.7 伺服器性能最佳化 20.7.1 作業系統參數 20.7.2 最佳化通訊端緩衝區 20.7.3 最佳化頻繁接收大檔案 20.7.4 最佳化TCP 連接 ▌20.8 本章複習 |
序
✤ 為什麼要寫這本書
隨著網際網路的不斷發展,CPU 硬體的核心數也在不斷提升,並行程式設計越來越普及,但是並行程式設計並不像其他業務那樣簡單明了。 在撰寫並行程式時,往往會出現各種各樣的Bug,這些Bug 常常以某種「詭異」的形式出現,然後迅速消失,並且在大部分場景下難以複現。所以,高並行程式設計著實是一項讓程式設計師頭疼的技術。 本書從實際需求出發,全面細緻地介紹了高並行程式設計的基礎知識、核心原理、實戰案例和系統架構等內容。每個章節都根據實際需要配有相關的原理圖和流程圖,在實戰案例篇,還會提供完整的實戰案例原始程式。書中的每個解決方案都經過高並行、大流量的生產環境的考驗,可以用於解決實際生產環境中的高並行問題。透過閱讀和學習本書,讀者可以更加全面、深入、透徹地理解高並行程式設計知識,提高對高並行程式設計問題的處理能力和專案實戰能力,並站在更高的層面解決高並行程式設計系統架構問題。
✤ 讀者對象 ■網際網路從業人員。 ■中高級開發人員。 ■架構師。 ■技術經理。 ■技術專家。 ■想轉行從事高並行程式設計的人員。 ■需要系統學習高並行程式設計的開發人員。 ■需要提高並行程式設計開發水準的人員。 ■需要時常查閱高並行程式設計技術和開發案例的人員。
✤ 本書特色 1. 系統介紹高並行程式設計的知識 目前,圖書市場少有全面細緻地介紹有關高並行程式設計的基礎知識、核心原理、實戰案例和系統架構的圖書,多從其中一兩個角度入手講解。本書從以上四方面入手,全面、細緻並且層層遞進地介紹了高並行程式設計相關知識。 2. 大量圖解和開發案例 為了便於理解,筆者在高並行程式設計的基礎知識、核心原理和系統架構章節中配有大量的圖解和圖表,在實戰案例章節中配有完整的高並行程式設計案例。讀者按照本書的案例學習,並運行案例程式,能夠更加深入地理解和掌握相關知識。另外,這些案例程式和圖解的draw.io 原文件會一起收錄於隨書資料裡。讀者也可以造訪下面的連結,獲取完整的實戰案例原始程式和相關的隨書資料。 ■GitHub:github.com/binghe001/mykit-concurrent-principle。 ■Gitee:gitee.com/binghe001/mykit-concurrent-principle。 3. 案例應用性強 對於高並行程式設計的各項技術點,書中都配有相關的典型案例,具有很強的實用性,方便讀者隨時查閱和參考。 4. 具有較高的實用價值 書中大量的實戰案例來自筆者對實際工作的複習,尤其是實戰案例篇與系統架構篇涉及的內容,其中的完整案例稍加修改與完善便可應用於實際的生產環境中。
✤ 本書內容及知識系統 第1篇 基礎知識(第1~2章) 本篇簡單地介紹了作業系統執行緒排程的相關知識和並行程式設計的基礎知識。作業系統執行緒排程的知識包括馮· 諾依曼系統結構、CPU 架構、作業系統執行緒和Java 執行緒與作業系統執行緒的關係。並行程式設計的基礎知識包括並行程式設計的基本概念、並行程式設計的風險和並行程式設計中的鎖等。 第2篇 核心原理(第3~14章) 本篇使用大量的圖解詳細介紹了並行程式設計中各項技術的核心原理,涵蓋並行程式設計的三大核心問題、並行程式設計的本質問題、原子性的核心原理、可見性與有序性核心原理、synchronized 核心原理、AQS核心原理、Lock 鎖核心原理、CAS 核心原理、鎖死的核心原理、鎖最佳化、執行緒池核心原理和ThreadLocal 核心原理。 第3篇 實戰案例(第15~18章) 本篇在核心原理篇的基礎上,實現了4 個完整的實戰案例,包括手動開發執行緒池實戰、基於CAS 實現自旋鎖實戰、基於讀/ 寫鎖實現快取實戰和基於AQS 實現可重入鎖實戰。每個實戰案例都是核心原理篇的落地實現,掌握這4 個實戰案例的實現方式,有助我們更進一步地在實際專案中開發高並行程式。 第4篇 系統架構(第19~20章) 本篇以高並行、大流量場景下典型的分散式鎖架構和秒殺系統架構為例,深入剖析了分散式鎖和秒殺系統的架構細節,讓讀者能夠站在更高的架構層面來理解高並行程式設計。
✤ 如何閱讀本書 ■對於沒有接觸過高並行程式設計或高並行程式設計技術薄弱的讀者,建議按照順序從第1 章開始閱讀,並實現書中的每一個案例。 ■對於有一定多執行緒和並行程式設計基礎的讀者,可以根據自身實際情況,選擇性地閱讀相關篇章。 ■對本書中涉及的高並行程式設計案例,讀者可以先自行思考其實現方式,再閱讀相關內容,可達到事半功倍的學習效果。 ■可以先閱讀一遍書中的高並行程式設計案例,再閱讀各種技術對應的原理細節,理解會更加深刻。
✤ 勘誤和支援 由於作者的水準有限,撰寫時間倉促,書中難免會出現一些錯誤或不妥之處,懇請讀者批評指正。如果讀者對本書有任何建議或想法,請聯繫筆者。 電子郵件:1028386804@qq.com。
✤ 致謝 感謝蔣濤(CSDN 創始人、總裁)、鄒欣(CSDN 副總裁)、右軍(螞蟻金服資深技術專家)、季敏(阿里中介軟體分散式事務團隊負責人)、於雨(Dubbo-go 社區負責人)、張開濤(高德資深技術專家)、孫玄(奈學科技創始兼CEO、58 集團前技術委員會主席)、沈劍(網際網路架構專家、公眾號「架構師之路」作者)、程軍(餓了嗎前技術總監、公眾號「軍哥手記」作者)、李鵬雲(杭州任你說智慧科技CTO)、李偉(Apache RocketMQ 北京社區聯合發起人)、駱俊武(京東零售架構師)、Mr.K(「技術領導力」公眾號作者、某電子商務公司CTO)、「純潔的微笑(純潔的微笑」公眾號作者)、翟永超(公眾號「程式猿DD」維護人、《Spring Cloud 微服務實戰》作者)(以上排名不分先後)等行業大佬對本書的大力推薦。 感謝作者技術社區的兄弟姐妹們,感謝你們長期對社區的支援和貢獻。 你們的支援是我寫作的最大動力。 感謝我的團隊和許許多多一起合作、交流過的朋友們,感謝部落格、公眾號的粉絲,以及在我部落格、公眾號留言及鼓勵我的朋友們。 感謝電子工業出版社博文視點的張晶編輯,在這幾個月的時間中始終支援我寫作,你的鼓勵和幫助引導我順利完成全部書稿。 感謝我的家人,他們都在以自己的方式在我寫作期間默默地給予我支援與鼓勵,並時時刻刻為我灌輸著信心和力量! 最後,感謝所有支援、鼓勵和幫助過我的人。謹以此書獻給我最親愛的家人,以及許多關注、認可、支援、鼓勵和幫助過我的朋友們!
冰河 |