1. 程式人生 > >JAVA併發鎖 - 悲觀鎖VS樂觀鎖(一)

JAVA併發鎖 - 悲觀鎖VS樂觀鎖(一)

文章目錄


在討論鎖相關概念和原理之前,我們先來了解一下執行緒安全的問題,執行緒安全主要有以下兩方面影響:
1.操作中存在臨界資源,也稱共享資源。
2.系統中存在多執行緒操作臨界資源。

常見的解決方案:
當系統中存在多個執行緒操作臨界資源時,我們需要保證執行緒之間的共享資源可見,當其中一個執行緒獲取到操作共享資源的權利後,會對該資源進行加鎖限制,防止其它執行緒再對該資源進行修改,當該執行緒操作完後,會釋放資源鎖。

悲觀鎖VS樂觀鎖

在併發操作中,為了實現執行緒之間的資源共享,保證資料的一致性,通常需要進行執行緒間資料同步,在java中同步有很多種方式,其中 synchronized 是最常見的一種實現資源同步的方式,對資源進行加鎖。接下來我們首先研究下 悲觀鎖和樂觀鎖。簡單總結如下圖所示:
在這裡插入圖片描述

1.悲觀鎖

1.1什麼是悲觀鎖

悲觀鎖:執行緒進行併發操作時,總是以最壞的情況進行操作,假設總有其它執行緒會對資源進行更新,所以,當執行緒獲取到資源時,會對資源進行加鎖操作,避免其它執行緒對資源進行更新,等待當前執行緒操作完後,會釋放鎖,此時其它執行緒可以獲取資源,並完成相應的操作。

1.2原始碼分析

synchronized

synchronized 關鍵字在java中使用很頻繁,使用該關鍵字可以資源進行加鎖,本質上採用搶佔式獲取鎖的機制,是一種典型的悲觀鎖。synchronized 也是一種互斥鎖。關於互斥鎖將在後續文章中做出說明。

  • 三種應用方式

例項方法塊
靜態方法塊
程式碼塊

  • 底層原理
  • java虛擬機器對synchronized的優化
  • 關注點

Lock

1.3應用場景

悲觀鎖應用場景:
併發訪問中存在頻繁更新資料操作。

1.4實現

2樂觀鎖

2.1什麼是樂觀鎖

樂觀鎖:執行緒進行併發操作時,總是以最好的情況進行操作,假設沒有其它執行緒會對資源進行操作,如果當前執行緒只是進行查詢操作,那麼獲取到當前最新的資料返回給介面即可,【至於這個共享資源在獲取過程中會被其它執行緒更改,獲取到的資源可能不是最新的,導致出現這個問題應該歸於其它執行緒更新共享資源的一種機制】。如果當前執行緒需要對共享資源進行更新操作,那麼常常會採用一種校對更換的機制,即 CAS(Compare And Swap)。CAS原理將在下面進行介紹。

2.2原始碼分析

CAS 原理

cas是一種無鎖機制,在不使用鎖的情況下實現多執行緒之間的資源共享,cas中有三個值:需要讀寫的記憶體值V,需要進行比較的值A,需要更新的值B(需要寫入記憶體)。

當且僅當V == A時,才會進行更新操作V=B(將V值替換為B),更新操作是一個不斷重試的機制,如果不滿足V==A,會一直重試,直到滿足後作更新操作。

CAS 問題

  • ABA問題
  • 更新重試操作耗資源
  • 只能對一個變數作原子操作

2.3應用場景

併發訪問中存在頻繁查詢資料操作

2.4實現

總結

悲觀鎖是一種搶佔式鎖,獲取資源後,對資源進行加鎖,保證只有當前執行緒可進行操作,其它執行緒繼續阻塞,等待當前執行緒處理完釋放鎖後,才可進行資源爭奪。悲觀鎖適合於頻繁更新的操作,比如資料庫更新時表鎖等。

樂觀鎖實際上並未對共享資源進行加鎖,而是採用比較更新的(cas)機制,保證多執行緒之間共享資源的一致性。更新操作是一個不斷重試的操作。樂觀鎖適合於頻繁查詢的操作。


未完待續…