天天看點

幾種常見鎖的了解

對幾種常見鎖的了解:

悲觀鎖:在每次取資料時,總是擔心資料會被其他線程修改,是以會在取資料前先加鎖(讀鎖,寫鎖,行鎖等),當其他線程想要通路資料時,被阻塞挂起。可以依靠資料庫實作,如行鎖,讀鎖,寫鎖等。Java中synchronized也是悲觀鎖思想。

樂觀鎖:每次取資料時候,總是樂觀的認為資料不會被其他線程修改,是以不上鎖。但是在更新資料前,會判斷其他資料在更新前有沒有對資料進行修改。主要采用兩種方式:版本号機制和CAS操作。

Version機制:在資料庫表中加一個資料version字段,表示資料被修改的次數。當資料被修改時version加一。讀取資料同時也會讀取到version值,當送出更新時,如果剛才讀取的version值和目前資料庫的version值相等才更新。否則重試更新操作,直到更新成功。

CAS操作:當需要更新資料時,判斷目前記憶體值和之前取得的值是否相等。如果相等則用新值更新。若不等則失敗,失敗則重試,一般是一個自旋的過程,即不斷重試。

自旋鎖:線程的挂起和恢複操作都會轉入核心态完成,這些操作給系統的并發性能帶來很大壓力。很多時候,共享資料的鎖定狀态隻會持續很短一段時間。為了這麼短的時間挂起和恢複線程不值得。如果計算機有一個以上的處理器,可以讓兩個線程同時并行執行,我們就會讓後面那個線程稍等一下,但是不放棄處理器執行時間,看看持有鎖的線程是否很快釋放鎖。為了讓線程稍等一下,我們需要讓線程執行一個忙循環(自旋),這項技術就是自旋鎖。

自适應自旋鎖:自适應表示自旋鎖的自旋時間不再固定,根據前一次在這個鎖上的自旋時間以及鎖的擁有者的狀态自動調整。例如:如果同一個鎖對象,自旋等地剛剛獲得多鎖,那麼這次再次獲得這個鎖的可能性很大,是以這次允許自旋等待更長時間。相反,如果某個鎖對象沒有被獲得過,以後獲得這個鎖的自旋等待時間就設定的短一些。這樣的自适應自旋鎖很好的避免了處理器資源的浪費。

鎖消除:虛拟機即時編譯時候,對一些代碼需要同步,但是對于被檢測到的不可能進行共享資料競争的鎖進行消除。

公平鎖:公平鎖就是很公平的鎖,每個線程按照先來後到的順序獲得鎖,能保證每個線程隻要等待總能獲得鎖。一個線程獲得鎖過程是,先看這個鎖維護的等待隊列,如果等待隊列為空,或者目前想獲得鎖的線程是隊列裡的第一個,就讓這個線程獲得鎖,否者把這個線程放到等待隊列尾部,以後按照先來後到順序,等到時候取出自己執行。

非公平鎖:非公平鎖就是不公平的鎖,某個線程一來就開始嘗試占有鎖,這樣可能導緻某個線程占有不到鎖。如果嘗試失敗,則把它放到隊列裡。執行類似于公平鎖的過程。Synchronized是非公平鎖,reetrantlock預設下也是非公平鎖,但是在構造函數中,可以設定為公平的。

非公平鎖比公平鎖更能利用CPU資源,是以性能更高。但是公平鎖會給業務增加可控制性。

繼續閱讀