Java并發小結01
主要參考自《實戰Java高并發程式設計》,
需要知道的概念
- 同步與異步
- 并發與并行
- 臨界區
- 阻塞與非阻塞
- 死鎖、饑餓、活鎖
同步與異步
同步:同步方法一旦被呼叫,必須等待方法回傳后才能繼續后續的行為,
異步:異步方法就像一個訊息傳遞,被呼叫后方法會立即回傳,呼叫者可以開始后續的行為,
并發與并行
并行:兩個任務同時執行,
并發:一段時間內,多個任務在CPU交替執行,看似并行,
臨界區
用來表示一種可以被多個執行緒使用的公共資源,但是一次只能一個執行緒使用,一旦臨界區被占用,其他執行緒只能等待,
比如說列印機:一次只能列印一份檔案,要是交替列印,那么列印出來的東西是不可用的,
阻塞與非阻塞
阻塞:一個執行緒占用了臨界區資源,其他執行緒需要這個資源就得等待,等待會導致執行緒掛起,這就是阻塞,
非阻塞:與阻塞相反,沒有一個執行緒可以導致其他執行緒阻塞,所有執行緒都不斷嘗試繼續執行,
死鎖、饑餓、活鎖
死鎖:兩個或兩個以上執行緒相互請求其他執行緒的資源,誰都執行不下去,
饑餓:一個執行緒因為種種原因一直獲取不到需要的資源導致無法執行,
活鎖:執行緒之間將資源相互推讓而沒有一個執行緒拿到資源繼續執行,
并發級別
- 阻塞
- 無饑餓
- 無障礙
- 無鎖
- 無等待
阻塞
使用synchronized關鍵字或重入鎖,得到的就是阻塞的執行緒,
無饑餓
執行緒默認是不公平的(理論上優先滿足優先級高的),會導致饑餓,公平鎖解決饑餓問題,
無障礙
無障礙是一種最弱的非阻塞調度,兩個執行緒如果無障礙地運行,那么不會因為臨界區的問題導致一方被掛起,如果資料壞了就回滾,沒有資料競爭就順利完成作業,走出臨界區,
無障礙有可能會因為資料沖突一直回滾,一種可行的無障礙實作可以依賴一個“一致性標記”來實作,
無鎖
無鎖的并行都是無障礙的,無鎖的狀態下,所有的執行緒都能嘗試對臨界區進行訪問,不同的是,無鎖的并發保證必然有一個執行緒能夠在有限步內完成操作離開臨界區,
會出現執行緒饑餓,
無鎖的特點:可能會包含一個無窮回圈,在這個回圈中,執行緒會不斷地嘗試修改共享變數,如果沒有沖突,修改成功,走人,否則繼續嘗試,
無等待
無鎖只要求有一個執行緒在有限步內完成操作,而無等待則在無鎖的基礎上更近一步擴展,它要求所有執行緒都必須在有限步數內完成,這樣就不會引起饑餓問題,
JMM
探討一下java記憶體模型:原子性、可見性、有序性,
原子性:
一個操作是不可中斷的,
可見性
一個執行緒修改了某個共享變數的值時,其他執行緒會立馬知道這個修改,
有序性
程式在執行時,可能就進行指令排序,排序后的指令順序與原指令順序未必一致,
但是指令排序可以保證串行語意一致,不保證并行語意一致,
那些指令不能排序:Happen-Before原則
-
程式順序原則:一個執行緒內保證語意的串行性,
-
volatile 原則:volatile變數的寫先于讀發生,這保證了volatile變數的可見性,
-
鎖規則:解鎖(unlock)必然發生在隨后的加鎖(lock)前面,
-
傳遞性:A先于B,B先于C,那么A先于C,
-
執行緒的start()方法先于它的每一個動作,
-
執行緒的中斷(interrupt)先于被中斷執行緒的代碼,
-
物件的建構式的執行、結束先于finalize()方法,
個人小結:
這些都是概念性問題,如果第一次不太熟悉可以baidu一下進行理解,
作為《實戰Java高并發程式設計》的一章,主要介紹了并發的一些概念性關鍵詞,建議深入理解,后面的多執行緒并發操作都建立在這些概念之上,
其中第一章有一個小結介紹有關并行的兩個定律我忽略了,感興趣的可以自己去看: Amdahl定律和Gustafson定律,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/546801.html
標籤:其他
上一篇:卷起來!!!看了這篇文章我才知道MySQL事務&MVCC到底是啥?
下一篇:深度決議單例模式
