Java 高並發核心編程 捲2(加強版):多線程、鎖、JMM、JUC、高並發設計模式

尼恩、唐歡、孫精科、朱達華

  • 出版商: 清華大學
  • 出版日期: 2022-11-01
  • 定價: $708
  • 售價: 8.5$602
  • 語言: 簡體中文
  • ISBN: 7302620989
  • ISBN-13: 9787302620983
  • 相關分類: Design Pattern
  • 下單後立即進貨 (約4週~6週)

  • Java 高並發核心編程 捲2(加強版):多線程、鎖、JMM、JUC、高並發設計模式-preview-1
  • Java 高並發核心編程 捲2(加強版):多線程、鎖、JMM、JUC、高並發設計模式-preview-2
  • Java 高並發核心編程 捲2(加強版):多線程、鎖、JMM、JUC、高並發設計模式-preview-3
Java 高並發核心編程 捲2(加強版):多線程、鎖、JMM、JUC、高並發設計模式-preview-1

買這商品的人也買了...

商品描述

本書聚焦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工程師、架構師的編程參考書,又可以作為參加互聯網大廠面試、筆試的人員的學習參考書。

目錄大綱

目    錄

第1章  多線程原理與實戰 1

1.1  兩個技術面試故事 1

1.2  無處不在的進程和線程 2

1.2.1  進程的基本原理 3

1.2.2  線程的基本原理 4

1.2.3  進程與線程的區別 7

1.3  創建線程的4種方法 7

1.3.1  Thread類詳解 8

1.3.2  創建一個空線程 10

1.3.3  線程創建方法一:繼承Thread類創建線程類 11

1.3.4  線程創建方法二:實現Runnable接口創建線程目標類 12

1.3.5  優雅創建Runnable線程目標類的兩種方式 14

1.3.6  實現Runnable接口的方式創建線程目標類的優缺點 16

1.3.7  線程創建方法三:使用Callable和FutureTask創建線程 20

1.3.8  線程創建方法四:通過線程池創建線程 25

1.4  線程的核心原理 28

1.4.1  線程的調度與時間片 28

1.4.2  線程的優先級 29

1.4.3  線程的生命周期 31

1.4.4  一個線程狀態的簡單演示案例 33

1.4.5  使用Jstack工具查看線程狀態 35

1.5  線程的基本操作 36

1.5.1  線程名稱的設置和獲取 36

1.5.2  線程的sleep操作 38

1.5.3  線程的interrupt操作 39

1.5.4  線程的join操作 42

1.5.5  線程的yield操作 46

1.5.6  線程的daemon操作 48

1.5.7  線程狀態總結 52

1.6  線程池原理與實戰 54

1.6.1  JUC的線程池架構 54

1.6.2  Executors的4種快捷創建線程池的方法 56

1.6.3  線程池的標準創建方式 62

1.6.4  向線程池提交任務的兩種方式 63

1.6.5  線程池的任務調度流程 66

1.6.6  ThreadFactory(線程工廠) 68

1.6.7  任務阻塞隊列 70

1.6.8  調度器的鉤子方法 70

1.6.9  線程池的拒絕策略 72

1.6.10  線程池的優雅關閉 75

1.6.11  Executors快捷創建線程池的潛在問題 80

1.7  確定線程池的線程數 83

1.7.1  按照任務類型對線程池進行分類 83

1.7.2  為IO密集型任務確定線程數 84

1.7.3  為CPU密集型任務確定線程數 86

1.7.4  為混合型任務確定線程數 87

1.8  ThreadLocal原理與實戰 89

1.8.1  ThreadLocal的基本使用 89

1.8.2  ThreadLocal使用場景 91

1.8.3  使用ThreadLocal進行線程隔離 92

1.8.4  使用ThreadLocal進行跨函數數據傳遞 93

1.8.5  ThreadLocal內部結構演進 94

1.8.6  ThreadLocal源碼分析 96

1.8.7  ThreadLocalMap源碼分析 99

1.8.8  ThreadLocal綜合使用案例 102

第2章  Java內置鎖的核心原理 106

2.1  線程安全問題 106

2.1.1  自增運算不是線程安全的 106

2.1.2  臨界區資源與臨界區代碼段 108

2.2  synchronized關鍵字 109

2.2.1  synchronized同步方法 110

2.2.2  synchronized同步塊 110

2.2.3  靜態的同步方法 112

2.3  生產者-消費者問題 113

2.3.1  生產者-消費者模式 113

2.3.2  一個線程不安全的實現版本 114

2.3.3  一個線程安全的實現版本 120

2.4  Java對象結構與內置鎖 121

2.4.1  Java對象結構 121

2.4.2  Mark Word的結構信息 124

2.4.3  使用JOL工具查看對象的佈局 126

2.4.4  大小端問題 129

2.4.5  無鎖、偏向鎖、輕量級鎖和重量級鎖 131

2.5  偏向鎖的原理與實戰 132

2.5.1  偏向鎖的核心原理 132

2.5.2  偏向鎖的演示案例 133

2.5.3  偏向鎖的膨脹和撤銷 136

2.5.4  全局安全點原理和偏向鎖撤銷的性能問題 137

2.6  輕量級鎖的原理與實戰 139

2.6.1  輕量級鎖的核心原理 139

2.6.2  輕量級鎖的案例演示 141

2.6.3  輕量級鎖的分類 143

2.6.4  輕量級鎖的膨脹 144

2.7  重量級鎖的原理與實戰 144

2.7.1  重量級鎖的核心原理 144

2.7.2  重量級鎖的開銷 146

2.7.3  重量級鎖的演示案例 147

2.8  偏向鎖、輕量級鎖與重量級鎖的對比 149

2.9  線程間通信 150

2.9.1  線程間通信定義 150

2.9.2  低效的線程輪詢 150

2.9.3  wait方法、notify方法的原理 152

2.9.4  “等待-通知”通信模式演示案例 154

2.9.5  生產者-消費者之間的線程間通信 156

2.9.6  需要在synchronized同步塊的內部使用wait和notify 158

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

3.1  什麽是CAS 160

3.1.1  Unsafe類中的CAS方法 160

3.1.2  使用CAS進行無鎖編程 162

3.1.3  使用無鎖編程實現輕量級安全自增 164

3.1.4  字段偏移量的計算 165

3.2  JUC原子類 167

3.2.1  JUC中的Atomic原子操作包 167

3.2.2  基礎原子類AtomicInteger 168

3.2.3  數組原子類AtomicIntegerArray 170

3.2.4  AtomicInteger線程安全原理 171

3.3  對象操作的原子性 173

3.3.1  引用類型原子類 173

3.3.2  屬性更新原子類 174

3.4  ABA問題 175

3.4.1  瞭解ABA問題 175

3.4.2  ABA問題解決方案 177

3.4.3  使用AtomicStampedReference解決ABA問題 177

3.4.4  使用AtomicMarkableReference解決ABA問題 179

3.5  提升高並發場景下CAS操作的性能 180

3.5.1  以空間換時間:LongAdder 181

3.5.2  LongAdder的原理 183

3.6  CAS在JDK中的廣泛應用 189

3.6.1  CAS操作的弊端和規避措施 190

3.6.2  CAS操作在JDK中的應用 191

第4章  可見性與有序性原理 192

4.1  CPU物理緩存結構 192

4.2  並發編程的三大問題 194

4.2.1  原子性問題 194

4.2.2  可見性問題 195

4.2.3  有序性問題 196

4.3  硬件層的MESI協議原理 198

4.3.1  總線鎖和緩存鎖 199

4.3.2  MSI協議 201

4.3.3  MESI協議及RFO請求 201

4.3.4  Store Buffer和Invalidate Queue 206

4.3.5  volatile的原理 207

4.4  有序性與內存屏障 209

4.4.1  重排序 210

4.4.2  As-if-Serial規則 211

4.4.3  硬件層面的內存屏障 212

4.5  JMM詳解 214

4.5.1  什麽是Java內存模型 214

4.5.2  JMM與JMM物理內存的區別 216

4.5.3  JMM的8個操作 218

4.5.4  JMM如何解決有序性問題 219

4.6  Happens-Before規則 222

4.6.1  Happens-Before規則介紹 222

4.6.2  規則1:順序性規則 223

4.6.3  規則2:volatile規則 223

4.6.4  規則3:傳遞性規則 225

4.6.5  規則4:監視鎖規則 226

4.6.6  規則5:start()規則 227

4.6.7  規則6:join()規則 227

4.7  volatile語義中的內存屏障 228

4.7.1  volatile寫操作的內存屏障 229

4.7.2  volatile讀操作的內存屏障 229

4.7.3  對volatile變量的寫入進行性能優化 230

4.8  volatile不具備原子性 232

4.8.1  volatile變量的自增實例 232

4.8.2  volatile變量的復合操作不具備原子性的原理 233

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

5.1  顯式鎖 235

5.1.1  顯式鎖Lock接口 236

5.1.2  可重入鎖ReentrantLock 237

5.1.3  使用顯式鎖的模板代碼 239

5.1.4  基於顯式鎖進行“等待-通知”方式的線程間通信 241

5.1.5  LockSupport 244

5.1.6  顯式鎖的分類 247

5.2  悲觀鎖和樂觀鎖 249

5.2.1  悲觀鎖存在的問題 249

5.2.2  通過CAS實現樂觀鎖 249

5.2.3  不可重入的自旋鎖 250

5.2.4  可重入的自旋鎖 251

5.2.5  CAS可能導致“總線風暴” 252

5.2.6  CLH自旋鎖 254

5.3  公平鎖與非公平鎖 261

5.3.1  非公平鎖實戰 261

5.3.2  公平鎖實戰 262

5.4  可中斷鎖與不可中斷鎖 263

5.4.1  鎖的可中斷搶占 263

5.4.2  死鎖的監測與中斷 265

5.5  獨占鎖與共享鎖 268

5.5.1  獨占鎖 268

5.5.2  共享鎖Semaphore 268

5.5.3  共享鎖CountDownLatch 271

5.6  讀寫鎖 273

5.6.1  讀寫鎖ReentrantReadWriteLock 273

5.6.2  鎖的升級與降級 275

5.6.3  StampedLock 276

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

6.1  鎖與隊列的關系 280

6.2  AQS的核心成員 282

6.2.1  狀態標志位 282

6.2.2  隊列節點類 283

6.2.3  FIFO雙向同步隊列 284

6.2.4  JUC顯式鎖與AQS的關系 285

6.2.5  ReentrantLock與AQS的組合關系 285

6.3  AQS中的模板模式 287

6.3.1  模板模式 288

6.3.2  一個模板模式的參考實現 289

6.3.3  AQS的模板流程 291

6.3.4  AQS中的鉤子方法 291

6.4  通過AQS實現一把簡單的獨占鎖 292

6.4.1  簡單的獨占鎖的UML類圖 293

6.4.2  簡單的獨占鎖的實現 293

6.4.3  SimpleMockLock測試用例 295

6.5  AQS鎖搶占的原理 296

6.5.1  顯式鎖搶占的總體流程 296

6.5.2  AQS模板方法:acquire(arg) 297

6.5.3  鉤子實現:tryAcquire(arg) 297

6.5.4  直接入隊:addWaiter 297

6.5.5  自旋入隊:enq 298

6.5.6  自旋搶占:acquireQueued() 299

6.5.7  掛起預判:shouldParkAfterFailedAcquire 300

6.5.8  線程掛起:parkAndCheckInterrupt() 302

6.6  AQS兩個關鍵點:節點的入隊和出隊 302

6.6.1  節點的自旋入隊 303

6.6.2  節點的出隊 303

6.7  AQS鎖釋放的原理 304

6.7.1  SimpleMockLock獨占鎖的釋放流程 304

6.7.2  AQS模板方法:release() 305

6.7.3  鉤子實現:tryRelease() 305

6.7.4  喚醒後驅:unparkSuccessor() 306

6.8  ReentrantLock的搶鎖流程 306

6.8.1  ReentrantLock非公平鎖的搶占流程 307

6.8.2  非公平鎖的同步器子類 307

6.8.3  非公平搶占的鉤子方法:tryAcquire(arg) 308

6.8.4  ReentrantLock公平鎖的搶占流程 308

6.8.5  公平鎖的同步器子類 309

6.8.6  公平搶占的鉤子方法:tryAcquire(arg) 309

6.8.7  是否有後驅節點的判斷 310

6.9  AQS條件隊列 310

6.9.1  Condition基本原理 310

6.9.2  await()等待方法原理 312

6.9.3  signal()喚醒方法原理 313

6.9.4  節點入隊的時機 314

6.10  AQS的實際應用 315

第7章  JUC容器類 316

7.1  線程安全的同步容器類 316

7.2  JUC高並發容器 318

7.3  CopyOnWriteArrayList 319

7.3.1  CopyOnWriteArrayList的使用 320

7.3.2  CopyOnWriteArrayList原理 321

7.3.3  CopyOnWriteArrayList讀取操作 322

7.3.4  CopyOnWriteArrayList寫入操作 323

7.3.5  CopyOnWriteArrayList的迭代器實現 323

7.4  BlockingQueue 324

7.4.1  BlockingQueue的特點 324

7.4.2  阻塞隊列的常用方法 325

7.4.3  常見的BlockingQueue 326

7.4.4  ArrayBlockingQueue的基本使用 328

7.4.5  ArrayBlockingQueue構造器和成員 330

7.4.6  非阻塞式添加元素:add()、offer()方法的原理 332

7.4.7  阻塞式添加元素:put()方法的原理 333

7.4.8  非阻塞式刪除元素:poll()方法的原理 335

7.4.9  阻塞式刪除元素:take()方法的原理 335

7.4.10  peek()直接返回當前隊列的隊首元素 337

7.5  ConcurrentHashMap 337

7.5.1  HashMap和HashTable的問題 337

7.5.2  JDK 1.7版本ConcurrentHashMap的結構 338

7.5.3  JDK 1.7版本ConcurrentHashMap的核心原理 339

7.5.4  JDK 1.8版本ConcurrentHashMap的結構 346

7.5.5  JDK 1.8版本ConcurrentHashMap的核心原理 347

7.5.6  JDK 1.8版本ConcurrentHashMap的核心源碼 350

第8章  高並發設計模式 353

8.1  線程安全的單例模式 353

8.1.1  從餓漢式單例到懶漢式單例 353

8.1.2  使用內置鎖保護懶漢式單例 354

8.1.3  雙重檢查鎖方式 355

8.1.4  使用雙重檢查鎖+volatile 356

8.1.5  使用靜態內部類實例懶漢單例模式 357

8.2  Master-Worker模式 357

8.2.1  Master-Worker模式的參考實現 358

8.2.2  Netty中的Master-Worker模式的實現 362

8.2.3  Nginx中的Master-Worker模式的實現 363

8.3  ForkJoin模式 364

8.3.1  ForkJoin模式的原理 364

8.3.2  ForkJoin框架 365

8.3.3  ForkJoin框架使用實戰 366

8.3.4  ForkJoin框架的核心API 367

8.3.5  工作竊取算法 370

8.3.6  ForkJoin框架的原理 371

8.4  生產者-消費者模式 372

8.5  Future模式 373

第9章  異步回調模式 375

9.1  從泡茶的案例說起 375

9.2  join:異步阻塞之悶葫蘆 376

9.2.1  線程的合並流程 376

9.2.2  調用join()實現異步泡茶喝 376

9.2.3  join()方法詳解 377

9.3  FutureTask:異步調用之重武器 378

9.3.1  通過FutureTask獲取異步執行結果的步驟 379

9.3.2  使用FutureTask實現異步泡茶喝 379

9.4  異步回調與異步阻塞調用 382

9.5  Guava的異步回調模式 383

9.5.1  詳解FutureCallback 383

9.5.2  詳解ListenableFuture 384

9.5.3  ListenableFuture異步任務 384

9.5.4  使用Guava實現泡茶喝的實例 385

9.5.5  Guava異步回調和Java異步調用的區別 388

9.6  Netty的異步回調模式 389

9.6.1  GenericFutureListener接口詳解 389

9.6.2  Netty的Future接口詳解 389

9.6.3  ChannelFuture的使用 390

9.6.4  Netty的出站和入站異步回調 390

9.7  異步回調模式小結 391

第10章  CompletableFuture異步回調 392

10.1  CompletableFuture詳解 392

10.1.1  CompletableFuture的UML類關系 392

10.1.2  CompletionStage接口 393

10.1.3  使用runAsync和supplyAsync創建子任務 393

10.1.4  設置的子任務回調鉤子 394

10.1.5  調用handle()方法統一處理異常和結果 396

10.1.6  線程池的使用 397

10.2  異步任務的串行執行 398

10.2.1  thenApply()方法 398

10.2.2  thenRun()方法 399

10.2.3  thenAccept()方法 399

10.2.4  thenCompose()方法 400

10.2.5  4個任務串行方法的區別 401

10.3  異步任務的合並執行 402

10.3.1  thenCombine()方法 402

10.3.2  runAfterBoth()方法 404

10.3.3  thenAcceptBoth()方法 404

10.3.4  allOf()等待所有的任務結束 405

10.4  異步任務的選擇執行 405

10.4.1  applyToEither()方法 406

10.4.2  runAfterEither()方法 407

10.4.3  acceptEither()方法 407

10.5  CompletableFuture的綜合案例 408

10.5.1  使用CompletableFuture實現泡茶喝實例 408

10.5.2  使用CompletableFuture進行多個RPC調用 410

10.5.3  使用RxJava模擬RPC異步回調 411