樂觀鎖和悲觀鎖的理解及如何實現,有哪些實現方式?


悲觀鎖總是假設最壞的情況每次去拿數據的時候都認為別人會修改所以每 

次在拿數據的時候都會上鎖這樣別人想拿這個數據就會阻塞直到它拿到鎖 

統的關系型數據庫里邊就用到了很多這種鎖機制比如行鎖表鎖等讀鎖 

鎖等都是在做操作之前先上鎖再比如 Java 里面的同步原語 synchronized  

鍵字的實現也是悲觀鎖

樂觀鎖顧名思義就是很樂觀每次去拿數據的時候都認為別人不會修改 

以不會上鎖但是在更新的時候會判斷一下在此期間別人有沒有去更新這個數據

可以使用版本號等機制樂觀鎖適用於多讀的應用類型這樣可以提高吞吐量

像數據庫提供的類似於 write_condition 機制其實都是提供的樂觀鎖 Java

 java.util.concurrent.atomic 包下面的原子變量類就是使用了樂觀鎖的一種實 

現方式 CAS 實現的

樂觀鎖的實現方式

1、使用版本標識來確定讀到的數據與提交時的數據是否一致提交后修改版本標 

不一致時可以采取丟棄和再次嘗試的策略

2、java 中的 Compare and Swap  CAS ,當多個線程嘗試使用 CAS 同時更新 

同一個變量時只有其中一個線程能更新變量的值而其它線程都失敗失敗的 

線程並不會被掛起而是被告知這次競爭中失敗並可以再次嘗試。 CAS 操作 

中包含三個操作數 —— 需要讀寫的內存位置(V)、進行比較的預期原值(A)

和擬寫入的新值(B)。如果內存位置 V 的值與預期原值 A 相匹配那么處理器會自 

動將該位置值更新為新值 B。否則處理器不做任何操作

CAS 缺點

1、ABA 問題

比如說一個線程 one 從內存位置 V 中取出 A,這時候另一個線程 two 也從內存中 

取出 A,並且 two 進行了一些操作變成了 B,然后 two 又將 V 位置的數據變成 A,

這時候線程 one 進行 CAS 操作發現內存中仍然是 A,然后 one 操作成功盡管線 

 one  CAS 操作成功但可能存在潛藏的問題 Java1.5 開始 JDK  atomic

包里提供了一個類 AtomicStampedReference 來解決 ABA 問題

 180   485 2、循環時間長開銷大

對於資源競爭嚴重線程沖突嚴重的情況,CAS 自旋的概率會比較大從而浪 

費更多的 CPU 資源效率低於 synchronized。

3、只能保證一個共享變量的原子操作

當對一個共享變量執行操作時我們可以使用循環 CAS 的方式來保證原子操作

但是對多個共享變量操作時循環 CAS 就無法保證操作的原子性這個時候就可 

以用鎖


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM