併發相關知識總結(三)

2021-09-14 02:29:31 字數 2699 閱讀 7970

1、lock介面

關鍵點:(1)lock和synchronized的區別,後者是通過monitor+物件頭的方式控制線程的同步,鎖的獲取和釋放都是隱式完成的,而lock則是手把手的獲取與釋放鎖;(2)lock可以嘗試非阻塞的獲取鎖,以及超時獲取鎖,並且,與synchronized不同,獲取到鎖的執行緒能夠響應中斷,同時釋放鎖。

2、aqs

這個是重中之重!!這個部分在第一次看完的時候感覺完全沒懂,後面慢慢的通過閱讀原始碼以及實現其子類的原始碼才慢慢了解,同步器在我們的日常開發中並沒有被直接使用到,它是乙個負責構建鎖或者其他同步元件的基礎框架,這時書上的原話,翻譯過來就是,實現實現鎖的基礎框架,封裝了同步狀態管理、執行緒排隊以及等待喚醒等底層操作,主要包括一下幾個知識點:

state:乙個全域性的int型變數表示同步狀態,當需要更改同步狀態時,則通過getstate、setstate以及compareandsetstate來進行操作以保證狀態改變的安全性;

acquire:獨佔式獲取同步狀態,成功則返回,失敗則進入同步佇列等待(獨佔鎖的獲取實現,如寫鎖);

acquireinterruptibly:顧名思義,可以響應中斷的acquire方法;

tryacquirenanos:在acquireinterruptibly的基礎上增加了超時限制;

acquireshare:共享式的獲取同步狀態,與獨佔式的區別在於同一時刻可以有多個執行緒同時獲取到同步狀態(共享鎖的獲取實現,如讀鎖);

實現原理:

同步佇列:同步器依賴內部的乙個fifo同步佇列來完成同步佇列的管理,當獲取同步狀態失敗時,會將該執行緒構造成乙個node節點並將其加入同步佇列,同時阻塞當前執行緒。注意:設定尾節點時是cas操作,因為可能由於多個執行緒獲取同步狀態失敗而加入到尾節點,而設定頭結點則不需要,因為只有乙個執行緒可以成功獲取同步狀態;

同步狀態的獲取與釋放:包括獨佔式以及共享式同步狀態的獲取與釋放,一定要看這塊的原始碼;

3、重入鎖

重入鎖的定義即支援重入,支援乙個執行緒對資源反覆加鎖,在釋放的時候,也需要將鎖全部釋放才算完全釋放。reentrantlock使用syn變數控制重入鎖來控制鎖的策略,包括公平與非公平兩種(預設非公平),公平鎖即每次都是等待佇列中的第乙個節點獲得鎖,缺點是吞吐量會下降(由於執行緒的大量切換),非公平鎖則不是按照fifo規則來,比如第乙個請求不成功,則會切換到第二個節點請求鎖,這樣能夠提高吞吐量,缺點就是可能會造成飢餓。

4、讀寫鎖

讀寫鎖即讀鎖和寫鎖,通過減小鎖的粒度提高併發效能;讀操作時獲取讀鎖,寫操作時獲取寫鎖,當執行緒獲取到寫鎖時,後續的讀寫操作都會被阻塞,當寫鎖釋放之後,其餘的操作才能繼續執行,jdk提供的reentrantreadwritelock包括以下特性:公平性選擇、重進入以及鎖降級;這裡值得一提的是鎖降級,遵循獲取寫鎖、獲取讀鎖再釋放寫鎖的次序,將寫鎖降級為讀鎖,這裡的讀鎖是在寫鎖獲取之前獲取的,比如執行緒a獲取寫鎖修改資料,此時如果沒有獲取讀鎖就釋放了寫鎖,正好這時候執行緒b獲取了寫鎖修改了資料,那麼執行緒a就完全感知不到資料的變化,而提前獲取讀鎖則能阻塞執行緒b獲得寫鎖,這樣保證讀資料的正確性;其同步狀態是通過乙個32位的變數控制,高16位為讀狀態,低16位為寫狀態。

5、常用的併發容器

concurrenthashmap:略

concurrentlinkedqueue:使用hops常量控制tail節點的更新,只有距離大於hops才需要使用cas更新tail節點;

阻塞佇列:arrayblockingqueue, linkedblockingqueue, priorityblockingqueue, delayqueue, synchronousqueue, linkedtransferqueue, linkedblockingdequeue;實現原理:通知者模式,通過condition來實現put和take時的阻塞等待;

6、fork/join

關鍵點:工作竊取演算法,即某個執行緒從其他佇列裡竊取任務來執行,這樣可以充分利用執行緒進行平行計算,減少執行緒間的競爭,類似mapreduce(我是這麼理解的),包括fork(分割任務)和join(執行任務合併結果)的過程。

實現原理:

fork:呼叫forkjoinworkerthread的pushtak方法非同步的執行任務,然後立即返回結果,將當前任務存放在forkjointask陣列佇列中,然後呼叫signalwork方法喚醒或建立乙個工作執行緒來執行任務;

join:用四種狀態值來判斷dojoin方法是否完成;

7、13種原子操作類

atomicboolean:原子更新布林型別,其本質也是先轉整形;

atomicinteger:原子更新整形;

atomiclong:原子更新長整形;

atomicintegerarray:原子更新陣列整形陣列裡的元素;

atomiclongarray:原子更新長整形陣列裡的元素;

atomicreferencearray:原子更新引用型別陣列裡的元素;(這裡需要指出185頁的乙個錯誤,addandget方法應該是以原子方式將索引位置的元素更新為輸入值);

atomicreference:原子更新引用型別;

atomicreferencefieldupdater:原子更新引用型別裡的字段;

atomicmarkablereference:原子更新帶有標記位的引用型別(可以原子更新物件);

atomicintegerfieldupdater:原子更新整形的字段;

atomiclongfieldupdater:原子更新長整形欄位的更新器;

atomicstampedreference:原子更新帶有版本號的引用型別(可以解決aba問題);

併發相關知識總結(四)

基本的用法就是定義計數器n,並通過await方法阻塞執行緒,直到n變成0。和join最直觀的使用區別就是不用手動的去掛起了,一兩個執行緒可能並不會顯得多方便,但是當執行緒數量較大時,區別還是很明顯的。這個我也沒用過,其字面意思就是可迴圈使用的屏障,讓一組執行緒到達乙個屏障 同步點 時被阻塞,直到最後...

併發程式設計的知識總結

對併發領程式設計從全面的去看待,可以抽象成三個核心問題 分工 同步 互斥 分工 分工重要且複雜 同步 乙個執行緒完成任務後,如何通知執行後續任務的執行緒 互斥 同一時刻,只允許乙個執行緒訪問共享變數 併發程式設計有三大問題 可見性 原子性 有序性 可見性產生的原因 計算機記憶體和cup的速度相差很多...

引用相關知識總結

1.什麼是 引用 申明和使用 引用 要注意哪些問題?答 引用就是某個目標變數的 別名 alias 對應用的操作與對變數直接操作效果完全相同。申明乙個引用的時候,切記要對其進行初始化。引用宣告完畢後,相當於目標變數名有兩個名稱,即該目標原名稱和引用名,不能再把該引用名作為其他變數名的別名。宣告乙個引用...