大家好,我是冰河~~
今天給小夥伴們帶來一篇我整理了一個月的並行程式設計最佳學習路線,這應該是全網最全的並行程式設計學習路線了吧!希望能夠為小夥伴們帶來實質性的幫助。
如果文章對你有點幫助,還請小夥伴們點贊、收藏、評論、分享呀,讓更多的小夥伴看到,一起進階,一起成長~~
先來看下我花了一個月整理的並行程式設計腦圖吧,這應該是全網最全的了!!
記憶體共用
訊息傳遞
重排序
為了程式的效能,處理器、編譯器都會對程式進行重排序處理
條件
問題
順序一致性
多執行緒環境下的理論參考模型
為程式提供了極強的記憶體可見性保證
特性
happens-before
JMM中最核心的理論,保證記憶體可見性
在JMM中,如果一個操作執行的結果需要對另一個操作可見,那麼這兩個操作之間必須存在happens-before關係。
理論
as-if-serial
同步、重量級鎖
原理
鎖物件
實現機制
Java物件頭
synchronized的鎖就是儲存在Java物件頭中的
包括兩部分資料
Mark Word(標記欄位)
Mark Word被設計成一個非固定的資料結構以便在極小的空間記憶體儲存儘量多的資料,它會根據物件的狀態複用自己的儲存空間
包括
Klass Pointer(型別指標)
monitor
Owner
鎖優化
自旋鎖
該執行緒等待一段時間,不會被立即掛起,看持有鎖的執行緒是否會很快釋放鎖(迴圈方式)
自旋字數較難控制(-XX:preBlockSpin)
存在理論:執行緒的頻繁掛起、喚醒負擔較重,可以認為每個執行緒佔有鎖的時間很短,執行緒掛起再喚醒得不償失
缺點
適應性自旋鎖
鎖消除
若不存在資料競爭的情況,JVM會消除鎖機制
判斷依據
鎖粗化
輕量級鎖
在沒有多執行緒競爭的前提下,減少傳統的重量級鎖使用作業系統互斥量產生的效能消耗
通過CAS來獲取鎖和釋放鎖
效能依據
缺點
偏向鎖
特性
實現機制
記憶體語意
作業系統語意
主記憶體、快取記憶體(執行緒私有)快取一致?
解決方案
記憶體模型
單例模式
DCL
解決方案
volatile方案
基於類初始化的解決方案
AbstractQueuedSynchronizer,同步器,實現JUC核心基礎元件
解決了子類實現同步器時涉及的大量細節問題,例如獲取同步狀態、FIFO同步佇列
採用模板方法模式,AQS實現大量通用方法,子類通過繼承方式實現其抽象方法來管理同步狀態
CLH同步佇列
同步狀態獲取與釋放
獨佔式
獲取鎖
釋放鎖
共用式
獲取鎖
釋放鎖
執行緒阻塞和喚醒
當有執行緒獲取鎖了,其他再次獲取時需要阻塞,當執行緒釋放鎖後,AQS負責喚醒執行緒
LockSupport
Compare And Swap,整個JUC體系最核心、最基礎理論
記憶體值V、舊的預期值A、要更新的值B,當且僅當記憶體值V的值等於舊的預期值A時才會將記憶體值V的值修改為B,否則什麼都不幹
native中存在四個引數
缺陷
迴圈時間太長
只能保證一個共用變數原子操作
ABA問題
解決方案
它允許一組執行緒互相等待,直到到達某個公共屏障點 (common barrier point)
通俗講:讓一組執行緒到達一個屏障時被阻塞,直到最後一個執行緒到達屏障時,屏障才會開門,所有被屏障攔截的執行緒才會繼續幹活
底層採用ReentrantLock + Condition實現
應用場景
在完成一組正在其他執行緒中執行的操作之前,它允許一個或多個執行緒一直等待
用給定的計數 初始化 CountDownLatch。由於呼叫了 countDown() 方法,所以在當前計數到達零之前,await 方法會一直受阻塞。之後,會釋放所有等待的執行緒,await 的所有後續呼叫都將立即返回。這種現象只出現一次——計數無法被重置。如果需要重置計數,請考慮使用 CyclicBarrier。
與CyclicBarrier區別
內部採用共用鎖來實現
號誌
從概念上講,號誌維護了一個許可集。如有必要,在許可可用前會阻塞每一個 acquire(),然後再獲取該許可。每個 release() 新增一個許可,從而可能釋放一個正在阻塞的獲取者。但是,不使用實際的許可物件,Semaphore 只對可用許可的號碼進行計數,並採取相應的行動
號誌Semaphore是一個非負整數(>=1)。當一個執行緒想要存取某個共用資源時,它必須要先獲取Semaphore,當Semaphore >0時,獲取該資源並使Semaphore – 1。如果Semaphore值 = 0,則表示全部的共用資源已經被其他執行緒全部佔用,執行緒必須要等待其他執行緒釋放資源。當執行緒釋放資源時,Semaphore則+1
應用場景
內部採用共用鎖實現
一種解決多執行緒環境下成員變數的問題的方案,但是與執行緒同步無關。其思路是為每一個執行緒建立一個單獨的變數副本,從而每個執行緒都可以獨立地改變自己所擁有的變數副本,而不會影響其他執行緒所對應的副本
ThreadLocal 不是用於解決共用變數的問題的,也不是為了協調執行緒同步而存在,而是為了方便每個執行緒處理自己的狀態而引入的一個機制
四個方法
ThreadLocalMap
注意點
記憶體漏失問題
ThreadLocalMap
顯示呼叫remove()
一個用於並行執行任務的框架, 是一個把大任務分割成若干個小任務,最終彙總每個小任務結果後得到大任務結果的框架
核心思想
工作竊取
核心類
ForkJoinPool
ForkJoinTask
ForkJoinWorkerThread
CAS + Synchronized 來保證並行更新的安全,底層採用陣列+連結串列/紅黑樹的儲存結構
重要內部類
Node
TreeNode
TreeBin
ForwardingNode
輔助節點,用於ConcurrentHashMap擴容操作
sizeCtl
控制識別符號,用來控制table初始化和擴容操作的
含義
重要操作
initTable
ConcurrentHashMap初始化方法
只能有一個執行緒參與初始化過程,其他執行緒必須掛起
建構函式不做初始化過程,初始化真正是在put操作觸發
步驟
put
核心思想
步驟
get
步驟
擴容
多執行緒擴容
步驟
連結串列轉換為紅黑樹過程
1.8 與 1.7的區別
基於連結節點的無邊界的執行緒安全佇列,採用FIFO原則對元素進行排序,內部採用CAS演演算法實現
不變性
head的不變性和可變性
tail的不變性和可變性
精妙之處:利用CAS來完成資料操作,同時允許佇列的不一致性,弱一致性表現淋漓盡致
第三種key-value資料結構:SkipList(跳錶)
SkipList
平衡二元樹結構
Skip list讓已排序的資料分佈在多層連結串列中,以0-1亂數決定一個資料的向上攀升與否,通過「空間來換取時間」的一個演演算法,
在每個節點中增加了向前的指標,在插入、刪除、查詢時可以忽略一些不可能涉及到的結點,從而提高了效率
特性
查詢、刪除、新增
用於通過原子的方式更新基本型別
AtomicBoolean
AtomicInteger
AtomicLong
通過原子的方式更新陣列裡的某個元素
AtomicIntegerArray
AtomicLongArray
AtomicReferenceArray
如果要原子的更新多個變數,就需要使用這個原子更新參照型別提供的類
AtomicReference
AtomicReferenceFieldUpdater
AtomicMarkableReference
如果我們只需要某個類裡的某個欄位,那麼就需要使用原子更新欄位類
AtomicIntegerFieldUpdater
AtomicLongFieldUpdater
AtomicStampedReference
一個由陣列實現的FIFO有界阻塞佇列
ArrayBlockingQueue有界且固定,在建構函式時確認大小,確認後不支援改變
在多執行緒環境下不保證「公平性」
實現
支援優先順序的無界阻塞佇列
預設情況下元素採用自然順序升序排序,可以通過指定Comparator來對元素進行排序
二元堆積
分類
最大堆
最小堆
新增操作則是不斷「上冒」,而刪除操作則是不斷「下掉」
實現
支援延時獲取元素的無界阻塞佇列
應用
實現
Delayed介面
一個沒有容量的阻塞佇列
應用
難搞懂,與Exchanger 有一拼
連結串列組成的的無界阻塞佇列
相當於ConcurrentLinkedQueue、SynchronousQueue (公平模式下)、無界的LinkedBlockingQueues等的超集
預佔模式
由連結串列組成的雙向阻塞佇列
容量可選,在初始化時可以設定容量防止其過度膨脹,如果不設定,預設容量大小為Integer.MAX_VALUE
運用
降低資源消耗
提高響應速度
提高執行緒的可管理性
Executors
ThreadPoolExecutor
引數含義
corePoolSize
maximumPoolSize
keepAliveTime
unit
workQueue
用來儲存等待執行的任務的阻塞佇列
使用的阻塞佇列
threadFactory
handler
RejectedExecutionHandler,執行緒池的拒絕策略
分類
執行緒池分類
newFixedThreadPool
可重用固定執行緒數的執行緒池
分析
newCachedThreadPool
使用單個worker執行緒的Executor
分析
newSingleThreadExecutor
會根據需要建立新執行緒的執行緒池
分析
任務提交
任務執行
執行緒池調優
執行緒池監控
ScheduledThreadPoolExecutor
非同步計算
Future
提供操作
FutureTask
如果你想進大廠,想升職加薪,或者對自己現有的工作比較迷茫,都可以私信我交流,希望我的一些經歷能夠幫助到大家~~
推薦閱讀:
好了,今天就到這兒吧,小夥伴們點贊、收藏、評論,一鍵三連走起呀,我是冰河,我們下期見~~