關於樂觀鎖和悲觀鎖的概念

悲觀鎖

總是假設最壞的情況,每次去拿數據的時候都認爲別人會修改,所以每次在拿 數據的時候都會上鎖,這樣別人想拿這個數據就會阻塞直到它拿到鎖(共享資
源每次只給一個線程使用,其它線程阻塞,用完後再把資源轉讓給其它線 程)。傳統的關係型數據庫裏邊就用到了很多這種鎖機制,比如行鎖,表鎖
等,讀鎖,寫鎖等,都是在做操作之前先上鎖。Java中 synchronized和 ReentrantLock等獨佔鎖就是悲觀鎖思想的實現。

樂觀鎖

總是假設最好的情況,每次去拿數據的時候都認爲別人不會修改,所以不會上 鎖,但是在更新的時候會判斷一下在此期間別人有沒有去更新這個數據,可以
使用版本號機制和CAS算法實現。樂觀鎖適用於多讀的應用類型,這樣可以提
高吞吐量,像數據庫提供的類似於write_condition機制,其實都是提供的樂 觀鎖。在Java中
java.util.concurrent.atomic包下面的原子變量類就是使用了 樂觀鎖的一種實現方式CAS實現的。

使用場景
樂觀鎖適用於寫比較少的情況下(多讀場景)
悲觀鎖適用寫入比較多的場景(多寫入場景)
樂觀鎖怎麼實現

  1. 版本號機制
    一般是在數據表中加上一個數據版本號version字段,表示數據被修改的次 數,當數據被修改時,version值會加一。當線程A要更新數據值時,在讀取數 據的同時也會讀取version值,在提交更新時,若剛纔讀取到的version值爲當 前數據庫中的version值相等時才更新,否則重試更新操作,直到更新成功
    2CAS算法
    即compare and swap(比較與交換),是一種有名的無鎖算法。無鎖編程, 即不使用鎖的情況下實現多線程之間的變量同步,也就是在沒有線程被阻塞的 情況下實現變量的同步,所以也叫非阻塞同步(Non-blocking Synchronization)。CAS算法涉及到三個操作數
     需要讀寫的內存值 V
     進行比較的值 A
     擬寫入的新值 B
    當且僅當 V 的值等於 A時,CAS通過原子方式用新值B來更新V的值,否則 不會執行任何操作(比較和替換是一個原子操作)。一般情況下是一個自旋操 作,即不斷的重試

樂觀鎖可能會存在的問題
1 樂觀鎖的ABA問題
2 循環時間長開銷大
3 只能保證一個共享變量的原子操作

主要是面試總結的一些問題

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章