樂觀鎖與悲觀鎖

2021-09-11 23:11:51 字數 1108 閱讀 3364

悲觀鎖

共享資源每次只給乙個執行緒使用,其它執行緒阻塞,用完後再把資源轉讓給其它執行緒

總是假設最壞的情況,每次去拿資料的時候都認為別人會修改,所以每次在拿資料的時候都會上鎖,這樣別人想拿這個資料就會阻塞直到它拿到鎖

適用於多寫的場景

傳統的關係型資料庫裡邊行鎖,表鎖,讀鎖,寫鎖等就用到了這種鎖機制,都是在做操作之前先上鎖。

樂觀鎖總是假設最好的情況,每次去拿資料的時候都認為別人不會修改,所以不會上鎖,但是在更新的時候會判斷一下在此期間別人有沒有去更新這個資料

用版本號機制和cas演算法實現

適用於多讀的應用型別,這樣可以提高吞吐量

版本號機制

在資料表中加上乙個資料版本號version欄位,表示資料被修改的次數,當資料被修改時,version值會加一。

當執行緒a要更新資料值時,在讀取資料的同時也會讀取version值,在提交更新時,若剛才讀取到的version值為當前資料庫中的version值相等時才更新,否則重試更新操作,直到更新成功。

cas演算法

compare and swap(比較與交換),是一種有名的無鎖演算法。

使用鎖的情況下實現多執行緒之間的變數同步

在沒有執行緒被阻塞的情況下實現變數的同步,所以也叫非阻塞同步(non-blocking synchronization)

cas演算法涉及到三個運算元

需要讀寫的記憶體值 v

進行比較的值 a

擬寫入的新值 b

當且僅當 v 的值等於 a時,cas通過原子方式用新值b來更新v的值,否則不會執行任何操作(比較和替換是乙個原子操作)。

樂觀鎖的缺點

1 aba 問題

如果乙個變數v初次讀取的時候是a值,並且在準備賦值的時候檢查到它仍然是a值,那我們就能說明它的值沒有被其他執行緒修改過了嗎?很明顯是不能的,因為在這段時間它的值可能被改為其他值,然後又改回a,那cas操作就會誤認為它從來沒有被修改過。這個問題被稱為cas操作的 「aba」問題。

2 迴圈時間長開銷大

自旋cas(也就是不成功就一直迴圈執行直到成功)如果長時間不成功,會給cpu帶來非常大的執行開銷。

3 只能保證乙個共享變數的原子操作

cas 只對單個共享變數有效,當操作涉及跨多個共享變數時 cas 無效。

悲觀鎖與樂觀鎖

悲觀鎖與樂觀鎖 悲觀鎖 pessimistic locking 顧名思義就是採用一種悲觀的態度來對待事務併發問題,我們認為系統中的併發更新會非常頻繁,並且事務失敗 了以後重來的開銷很大,這樣以來,我們就需要採用真正意義上的鎖來進行實現。悲觀鎖的基本思想就是每次一 個事務讀取某一條記錄後,就會把這條記...

樂觀鎖與悲觀鎖

悲觀鎖 pessimistic locking 顧名思義就是採用一種悲觀的態度來對待事務併發問題,我們認為系統中的併發更新會非常頻繁,並且事務失敗了以後重來的開銷很大,這樣以來,我們就需要採用真正意義上的鎖來進行實現。悲觀鎖的基本思想就是每次乙個事務讀取某一條記錄後,就會把這條記錄鎖住,這樣 其它的...

樂觀鎖與悲觀鎖

鎖 locking 這個概念在我們學習多執行緒的時候曾經接觸過,其實這裡的鎖和多執行緒裡面處理併發的鎖是乙個道理,都是暴力的把資源歸為自己所有。這裡我們用到鎖的目的就是通過一些機制來保證一些資料在某個操作過程中不會被外界修改,這樣的機制,在這裡,也就是所謂的 鎖 即給我們選定的目標資料上鎖,使其無法...