前言

對一個 Java 程式設計師而言,併發程式設計能否熟練掌握是判斷他是不是優秀的重要標準之一。因為併發程式設計在 Java 語言中最為晦澀的知識點,它涉及記憶體、CPU、作業系統、程式語言等多方面的基礎能力,更加考驗一個程式設計師的內功深厚程度。

特別是當大資料時代的來臨,高併發更加成為了家常便飯,在工作中,我們總是繞不開併發程式設計的任務。比如說,你想寫個程式,一邊從檔案中讀取資料,一邊還要做實時計算…所以,想成為一名資深的 Java 後端工程師,併發程式設計是必須要牢牢把握的。那我們到底應該如何深入學習Java併發程式設計呢?

一、理論知識的掌握

  • 併發理論基礎
  1. 可見性、原子性和有序性問題:併發程式設計Bug的源頭
  2. 互斥鎖
  3. 管程:併發程式設計的萬能鑰匙
  4. Java執行緒

對於這上面的理論知識都要有去了解、掌握,以便以後能夠熟練的運用到實踐中去。

  • 併發工具類
  1. Lock&Condition
  2. Semaphore
  3. ReadWriteLock
  4. StampedLock

關於這幾個併發工具類,都要熟練掌握、熟練運用,還有很多併發工具類我沒有全部列舉出來,大家也需要多去學習與關注。多去了解與思考併發工具下,如何快速實現一個限流器?如何快速實現一個完備的快取?該怎麼利用這些工具類達到我們的目的。

  • 併發設計模式
  1. Immutability模式
  2. Copy-on-Write模式
  3. 執行緒本地儲存模式
  4. Balking模式
  5. Thread-Per-Message模式

這些模式也需要去了解,自己要去逐步研究這些模式下的運用規律,應該如何利用這些不變性解決併發問題,以及模式規範實現等。

  • 案例分析
  1. 高效能限流器Guava RateLiniter
  2. 高效能網路應用框架Netty
  3. 高效能佇列Disruptor
  4. 高效能資料庫連線池HiKariCP

多去做一些案例分析,研究各個案例間的異同點,多看一些案例分析對以後上手做任務有好處,能在從中吸取經驗。

  • 其他併發模型
  1. Actor模型:面向物件原生的併發模型
  2. 軟體實務記憶體:借鑑資料庫的併發經驗
  3. 協程:更輕量級的執行緒
  4. CSP模型:Golang的主力隊員

為了讓大家更加系統的掌握理論知識,在這裡給大家分享一篇有阿里p8大神耗時187天整理的《Java併發程式設計》。上述很多知識點都會在中涉及到,從基礎、高階、實踐的角度講解Java併發,讓你融匯貫通,形成全面系統的併發程式設計知識體系。最終可以得心應手地解決各種併發難題,同時將這些知識用於其他程式語言。一分辛勞,三分收穫。有需要完整版的朋友可以點選這裡進群領取

二、勤練程式碼

程式語言的學習是一個漫長的過程,欲速則不達,不可能一步登天,並且是沒有捷徑走的,所以我們唯一能做的就是堅持練習,在這個過程中慢慢積累經驗,把基礎打紮實。

學習Java理論知識是一項必不可少的內容,但是在理論學習時也要同時開始動手敲程式碼,別等到完全理解才動手,因為在程式執行中的各種情況都能幫助你快速理解,讓你更快更牢固地掌握知識點。只有保證每天都有一定的程式碼練習量,在遇到問題時才會有解決問題的思路。

然後不要認為寫出了一個簡單的小程式,就覺得自己已經學得非常好了,這只是程式設計學習過程中的一個小小實踐,要達到獨立做專案的程度還差一大截。

三、多做專案

對於學習不能只停留在理論以及基礎程式碼,這樣只會是紙上談兵,起不到任何的實際作用,想要真正能夠運用到實際生活、工作當中去,你就得開始去做專案了。

真正做專案時候會遇到的難題會更多,需要在看去不斷摸索與研究,可以多除錯,多嘗試用不用的方法實現,通過這樣的練習方式,對於Java的理論與實踐更加的融會貫通、運用自如,會非常熟練的掌握與運用Java,得到非常大的提升。

特別是自己認真的用程式碼做完一個專案之後,你會非常的有成就感,心裡說不出的喜悅,這個時候就要恭喜你,差不多已經掌握了Java這項語言。

四、經驗總結

自己要在學習與實踐中去總結經驗,無論是成功的或是失敗的,自己的或是他人的,都要照收不誤,從失敗的經驗中吸取教訓,在成功的經驗中做更多的嘗試,獲得更多的成功。

我也給大家分享幾點我的經驗:

  1. 在程式碼的練習和做專案的時候,一定要注意程式碼保持規範性,細緻瞭解程式碼機制,否則可能會導致整個專案發生錯誤。
  2. 不斷建立自己的人脈圈,不斷去結識新朋友,構建屬於自己的Java學習圈,
  3. 最後也是非常重要的一點,確保基礎知識的紮實性,提升自己分析問題、解決問題的能力,學無止境,強大到自己也能幫助別人解決問題,成為大佬級人物。

五、學習是最美好的字眼!

如今的網際網路大環境遍地裁員,焦慮人人都有。你要做的,只是在一家公司深耕一段時間,等能力、時機皆成熟,再抬頭看看外面的世界,你會發現自己的眼界和實力已經不可同日而語。

這裡是一篇大神耗時187天整理的《 Java 併發程式設計》,對併發程式設計的學習路徑做一個梳理,方便大家查漏補缺。需要的朋友可以通過評論區連接獲取


第一部分   Java 併發程式設計基礎篇

本篇主要介紹併發程式設計基礎知識,包含兩章內容,分別為併發程式設計執行緒基礎以及併發程式設計的其他概念與原理解析。


第一章  併發程式設計執行緒基礎

1.1 什麼是執行緒

1.2 執行緒建立與執行

1.3 執行緒通知與等待

1.4 等待執行緒執行終止的 join 方法

1.5 讓執行緒睡眠的 sleep 方法

1.6 讓出 CPU 執行權的 yield 方法

1.7 執行緒中斷

1.8 理解執行緒上下文切換

1.9執行緒死鎖

——1.9.1 什麼是執行緒死鎖

——1.9.2 何避免執行緒死鎖

1.10 守護執行緒與使用者執行緒

1.11 ThreadLocal

——1.11.1 ThreadLoca 使用示例

——1.11 2 ThreadLocal 的實現原理

——1.11.3 ThreadLocal 不支援繼承性

——1.11.4 InheritableThreadLocal


第二章  併發程式設計的其他基礎知識

2.1 什麼是多執行緒併發程式設計

2.2 為什麼要進行多執行緒併發程式設計

2.3 Java 中的執行緒安全問題

2.4 Java 中共享變 的記憶體可見性問題

2.5 Java 中的 synchronized 關鍵字

——2.5.1 synchronized 關鍵字介紹

——2.5.2 synchronized 的記憶體語義

2.6 Java 中的 volatile 關鍵字

2.7 Java 中的原子性操作

2.8 Java 中的 CAS 操作

2.9 Unsafe類

——2.9.1 Unsafe 類中的重要方法

——2.9.2 如何千史用 Unsafe 類

2.10 Java 指令重排序

2.11 偽共享

——2.11.1 什麼是偽共享

——2.11.2 為何會出現偽共享

——2.11.3 如何避免偽共享

——2.11.4 小結

2.12 鎖的概述

——2.12 1 樂觀鎖與悲觀鎖.

——2.12.2 公平鎖與非公平鎖

——2.12 3 獨佔鎖與共享鎖

——2.12.4 什麼是可重入鎖

2.13 總結

因為篇幅有限,這裡沒有辦法全部展示出來,只能列出目錄表格供大家參考,有需要完整版的朋友可以點選這裡領取


第二部分 Java 併發程式設計高階篇

在第一部分中我們介紹了併發程式設計的基礎知識,而本部分則主要講解併發包中一些主要元件的實現原理。


第三章  Java 併發包中 Thread Local Random 原理剖析

3 1 Random 類及其侷限性

3 2 ThreadLocalRandom

3 3 原始碼分析

3.4 總結


第四章  Java 併發包中原子操作類原理剖析

4.1 原子變數操作類

4.2 JDK8 新增的原子操作類 LongAdder

——4.2.1 LongAdder 簡單介紹

——4.2.2 LongAdder 程式碼分析

——4.2.3 小結

4.3 LongAccumulator 類原理探究

4.4 總結


第五章  Java 併發包中併發 List 原始碼剖析

5.1 介紹

5.2 主要方法原始碼解析

——5.2.1 初始化

——5 2.2 新增元素

——5.2.3 獲取指定位置元素

——5.2.4 修改指定

——5.2.5 刪除元素

——5.2.6 弱一致性的迭代器

5.3 總結


第六章  Java 併發包中鎖原理剖析

6.1 LockSuppo 工具類

6.2 抽象同步佇列 AQS 概述

——6.2.1 AQS——鎖的底層支援

——6.2.2 AQS——條件變數的支援

——6.2.3 基於AQS 實現自定義同步器

6.3 獨佔鎖 ReentrantLock 的原理

——6.3.1 類圖結構

——6.3.2 獲取鎖

——6.3.3 釋放鎖

——6.3.4 案例介紹

——6 3.5 小結

6.4 讀寫鎖 ReentrantReadWriteLock 的原理

——6 4.1 類圖結構

——6.4.2 寫鎖的獲取與釋放

——6.4.3 讀鎖的獲取與釋放

——6 4.4 案例介紹

——6 4.5 小結

6.5 JDK 8 中新增的 Sta mpedLock 鎖探究

——6.5.1 概述

——6.5.2 案例介紹

——6.5.3 小結


第七章  Java 併發包中併發佇列原理

7.1 ConcurrentLinkedQueue 原理探究

——7.1.1 類圖結構

——7.1.2 ConcurrentLinkedQueue 原理介紹

——7.1.3 小結

7.2 LinkedBlockingQueue 原理探究

——7.2.1 類圖結構

——7.2.2 LinkedBlockingQueue 原理介紹

——7.2.3 小結

7.3 ArrayB lockingQueue 原理探究

——7.3.1 類圖結構

——7.3.2 ArrayBlockingQueue原理介紹

——7.3.3 小結

7.4 PriorityBlockingQueue 原理探究

——7.4.1 介紹

——7.4.2 PriorityBlockingQueue 類圖 結構

——7.4.3 原理介紹

——7 4.4 案例介紹

——7.4.5 小結

7.5 DelayQueue 原理探究

——7.5.1 DelayQueue 類圖結構

——7.5.2 主要函式原理講解

——7 5.3 案例介紹

——7 5.4 小結


第八章  Java 併發包中執行緒池 ThreadPoolExecutor 原理探究

8.1 介紹

8.2 類圖介紹

8.3 原始碼分析

——8.3.1 public void execute(Runnable command)

——8.3.2 工作執行緒 Worker 的執行

——8 3.3 shutdown 操作

——8 3.4 shutdownNow 操作

——8.3.5 awaitTermination 操作

8.4 總結


第九章  Java 併發包中 ScheduledThreadPoolExecutor 原理探究

9.1 介紹

9.2 類圖介紹

9.3 原理剖析

——9.3.1 schedule(Runnable command, long delay,TimeUnit unit)方法

——9.3.2 scheduleWithFixedDelay(Runnable command,long initia!Del long delay, TimeUmt umt)方法

——9.3.3 scheduleAtFixedRate(Runnable command,long initia!Del long period,Time Unit unit)方法

9.4 總結


第十章  Java 併發包中執行緒同步器原理剖析

10.1 CountDownLatch 原理剖析

——10.1.1 案例介紹

——10 1.2 實現原理探究

——10.1.3 小結

10.2 迴環屏障 CyclicBarrier 原理探究

——10.2 1 案例介紹

——10.2.2 實現原理探究

——10.2.3 小結

10.3 訊號量 Semaphore 原理探究

——10 3.1 案例介紹

——10.3.2 實現原理探究

——10.3 3 小結

10.4 總結



第三部分 Java 併發程式設計實踐篇

在高階篇我們講解了 Java 中併發元件的原理實現,在這一篇我們則要進行實踐,只知道原理是不行的還應該知道怎麼在業務中使用。下面我們就來看看如何使用這些井發元件,以及進行併發程式設計時常會遇到哪些問題。


·第十一章  併發程式設計實踐

11.1 ArrayBlockingQueue 的使用

——11.1.1 非同步日誌列印模型概述

——11.1 2 非同步日誌與具體實現

——11.1.3 小結

11.2 Tomcat 的 NioEndPoint 中 ConcurrentLinkedQueue 的使用

——11.2.1 生產者——Acceptor 執行緒

——11.2.2 消費者——Poller 執行緒

——11 2.3 小結

11.3 併發元件 ConcurrentHashMap 使用注意事項

11.4 SimpleDateFormat 是執行緒不安全的

——11 4.1 問題復現s

——11.4.2 問題分析

——11.4.3 小結

11.5 使用 Ti mer 需要注意的事情

——11.5.1 問題的產生

——11.5.2 Timer 實現原理分析

——11.5.3 小結

11.6 對需要複用但是會被下游修改的引數要進行深複製

——11.6.1 問題的產生

——11.6.2 問題分析

——11.6.3 小結

11.7 建立執行緒和執行緒池時要指定與業務相關的名稱

——11.7.1 建立執行緒需要有執行緒名

——11.7.2 建立執行緒池時也需要指定執行緒池的名稱

——11.7 3 小結

11.8 使用執行緒池的情況下當程式結束時記得呼叫 shutdown 關閉執行緒池

——11.8.1 問題復現

——11.8.2 問題分析

——11.8.3 小結

11.9 執行緒池使用 FutureTask 需要注意的事情

——11 9.1 問題復現

——11.9.2 問題分析

——11 9.3 小結

11.10 使用 ThreadLocal 不當可能會導致記憶體洩漏

——11.10.1 為何會出現記憶體洩漏

——11.10.2 線上程池中使用 ThreadLocal 導致的記憶體洩漏

——11.10.3 Tomcat 的 servlet 使用 ThreadLoca 導致記憶體洩漏

——11.10.4 小結

11.11 總結

正文在這裡結束。因為文章內容實在是太多了,不能夠給大家一 一體現出來,每個章節都有更加細化的內容。

有需要完整版的朋友可以點選這裡進群找管理員領取