您現在的位置是:首頁 > 武術

關於Java中用到的鎖

  • 由 程式設計師的苦咖啡 發表于 武術
  • 2022-02-28
簡介十、偏向鎖Java偏向鎖(Biased Locking)是指它會偏向於第一個訪問鎖的執行緒,如果在執行過程中,只有一個執行緒訪問加鎖的資源,不存在多執行緒競爭的情況,那麼執行緒是不需要重複獲取鎖的,這種情況下,就會給執行緒加一個偏向鎖

鎖字怎麼寫好看

關於Java中用到的鎖

一、樂觀鎖

樂觀鎖,顧名思義,就是比較樂觀的鎖,當需要操作到共享資料時,它就認為沒有其它的執行緒在操作該資料,態度比較樂觀,

樂觀鎖操作資料時不會上鎖,在更新的時候會判斷一下在此期間是否有其他執行緒去更新這個資料。

樂觀鎖可以使用版本號機制和CAS演算法實現。在 Java 語言中 java。util。concurrent。atomic包下的原子類就是使用CAS 樂觀鎖實現的。適合讀多寫少的情況。

二、悲觀鎖

悲觀鎖就是和樂觀鎖截然不同的態度,當有一個執行緒操作共享資料時,它就會認為有其他執行緒也要和它做同樣的事情,不管三七二十一,索性就加鎖。

一個共享資料加了悲觀鎖,那執行緒每次想操作這個資料前都會假設其他執行緒也可能會操作這個資料,所以每次操作前都會上鎖,這樣其他執行緒想操作這個資料拿不到鎖只能阻塞了。

在 Java 語言中 synchronized 和 ReentrantLock等就是典型的悲觀鎖,還有一些使用了 synchronized 關鍵字的容器類如 HashTable 等也是悲觀鎖的應用。適合寫多讀少的情況。

三、獨佔鎖

獨佔鎖是指鎖一次只能被一個執行緒所持有。如果一個執行緒對資料加上獨佔鎖後,那麼其他執行緒不能再對該資料加任何型別的鎖。獲得獨佔鎖的執行緒即能讀資料又能修改資料。JDK中的synchronized和java。util。concurrent(JUC)包中Lock的實現類就是獨佔鎖。獨佔鎖也叫排它鎖。這裡就要提到互斥鎖了,互斥鎖是獨佔鎖的一種常規實現,是指某一資源同時只允許一個訪問者對其進行訪問,具有唯一性和排它性。

四、共享鎖

共享鎖是指鎖可被多個執行緒所持有。如果一個執行緒對資料加上共享鎖後,那麼其他執行緒只能對資料再加共享鎖,不能加獨佔鎖。獲得共享鎖的執行緒只能讀資料,不能修改資料。在 JDK 中 ReentrantReadWriteLock 就是一種共享鎖。而讀寫鎖是共享鎖的一種具體實現。讀寫鎖管理一組鎖,一個是隻讀的鎖,一個是寫鎖。讀鎖可以在沒有寫鎖的時候被多個執行緒同時持有,而寫鎖是獨佔的。寫鎖的優先順序要高於讀鎖,一個獲得了讀鎖的執行緒必須能看到前一個釋放的寫鎖所更新的內容。讀寫鎖相比於互斥鎖併發程度更高,每次只有一個寫執行緒,但是同時可以有多個執行緒併發讀。

五、公平鎖

公平鎖顧名思義,就是對於每一個執行緒都是公平的,會按照

申請鎖的順序來獲取鎖。俗話說:世界裡沒有絕對的公平,大家覺得公平鎖是絕對的公平嗎?

六、非公平鎖

非公平鎖是指多個執行緒獲取鎖的順序並不是按照申請鎖的順序,有可能後申請的執行緒比先申請的執行緒優先獲取鎖,在高併發環境下,有可能造成優先順序翻轉,或者飢餓的狀態(某個執行緒一直得不到鎖)。

七、可重入鎖

可重入鎖又稱之為遞迴鎖,是指同一個執行緒在外層方法獲取了鎖,在進入內層方法(內層方法也加了鎖)會自動獲取鎖。

八、自旋鎖

自旋鎖是指執行緒在沒有獲得鎖時不是被直接掛起,而是執行一個等待迴圈,這個等待迴圈就是所謂的自旋。自旋鎖的目的是為了減少執行緒被掛起的機率,因為執行緒的掛起和喚醒也都是耗資源的操作。如果鎖被另一個執行緒佔用的時間比較長,即使自旋了之後當前執行緒還是會被掛起,等待迴圈就會變成浪費系統資源的操作,反而降低了整體效能。因此自旋鎖是不適應鎖佔用時間長的併發情況的。在JDK1。6又引入了自適應自旋,這個就比較智慧了,自旋時間不再固定,由前一次在同一個鎖上的自旋時間以及鎖的擁有者的狀態來決定。如果虛擬機器認為這次自旋也很有可能再次成功那就會持續較多的時間,如果自旋很少成功,那以後可能就直接省略掉自旋過程,避免浪費處理器資源。

——————————————————以下是鎖升級相關概念————————————————————————————-

九、無鎖

無鎖狀態其實就是上面講的樂觀鎖。

十、偏向鎖

Java偏向鎖(Biased Locking)是指它會偏向於第一個訪問鎖的執行緒,如果在執行過程中,只有一個執行緒訪問加鎖的資源,不存在多執行緒競爭的情況,那麼執行緒是不需要重複獲取鎖的,這種情況下,就會給執行緒加一個偏向鎖。偏向鎖的實現是透過控制物件Mark Word的標誌位來實現的,如果當前是可偏向狀態,需要進一步判斷物件頭儲存的執行緒 ID 是否與當前執行緒 ID 一致,如果一致直接進入。

十、輕量級鎖

當執行緒競爭變得比較激烈時,偏向鎖就會升級為輕量級鎖,輕量級鎖認為雖然競爭是存在的,但是理想情況下競爭的程度很低,透過自旋方式等待上一個執行緒釋放鎖。

十一、重量級鎖

如果執行緒併發進一步加劇,執行緒的自旋超過了一定次數,或者一個執行緒持有鎖,一個執行緒在自旋,又來了其他執行緒訪問時,輕量級鎖就會膨脹為重量級鎖,重量級鎖會使除了此時擁有鎖的執行緒以外的執行緒都阻塞。升級到重量級鎖其實就是互斥鎖了,一個執行緒拿到鎖,其餘執行緒都會處於阻塞等待狀態。在 Java 中,synchronized 關鍵字內部實現原理就是鎖升級的過程:無鎖 ——> 偏向鎖 ——> 輕量級鎖 ——> 重量級鎖。

還有就是鎖最佳化技術,包括鎖粗化和鎖消除,鎖粗化就是將多個同步塊的數量減少,並將單個同步塊的作用範圍擴大,本質上就是將多次上鎖、解鎖的請求合併為一次同步請求。鎖消除是指虛擬機器編譯器在執行時檢測到了共享資料沒有競爭的鎖,從而將這些鎖進行消除。

Top