天天看點

樂觀鎖、悲觀鎖

文章目錄

    • 1 悲觀鎖
    • 2 樂觀鎖
      • 2.1 CAS算法 (Compare and Swap)
      • 2.2 版本号機制 -- 可用于解決ABA問題
    • 3 c++ 中用過哪些鎖?c++ 中有樂觀鎖嗎?

樂觀鎖對應于生活中樂觀的人總是想着事情往好的方向發展;

悲觀鎖對應于生活中悲觀的人總是想着事情往壞的方向發展。

1 悲觀鎖

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

共享資源每次隻給一個線程使用,其他線程阻塞,用完之後再把資源轉讓給其他線程。

2 樂觀鎖

總是假設最好的情況,每次去拿資料的時候都認為别人不會修改,是以不會上鎖。但是在更新的時候會判斷一下在此期間别人有沒有去更新這個資料,++可以使用版本号機制和CAS算法實作。++

2.1 CAS算法 (Compare and Swap)

是一種無鎖算法,即不使用鎖的情況下實作多線程之間的變量同步,也就是在沒有線程被阻賽的情況下實作變量的同步,是以也叫非阻賽同步。(Java語言)

CAS算法涉及到三個操作數:需要讀寫的記憶體值V、進行比較的值A、待寫入的新值B。

當且僅當V == A時,CAS通過原子操作用新值B來更新V值,否則不會執行任何操作。(比較+替換=一個原子操作)

CAS算法的缺點 -- ABA問題

如果一個變量V初次讀取的時候是A值,并且在準備指派的時候檢查到它仍然是A值,那麼我們就能說明它的值沒有被其他線程修改過嗎?
很明顯不是,因為在這段時間内它的值可能被改為其他值,然後又被改回A,那CAS操作就會認為它從來沒被改過。
這個問題被稱為CAS操作的 “ABA” 問題。
           

2.2 版本号機制 – 可用于解決ABA問題

一般是在資料表中加上一個資料庫版本号version字段,表述資料被修改的次數,當資料被修改時version值會加1。

當線程A要更新資料值時,在讀取資料的同時也會讀取version值,在送出更新時,若“剛才讀取到的version值”等于“目前資料庫中的version值”時才更新,否則重試更新操作,直到更新成功。

3 c++ 中用過哪些鎖?c++ 中有樂觀鎖嗎?

c++線程之間的鎖有:程序和線程的部落格有講

  • 互斥鎖
  • 條件鎖
  • 自旋鎖
  • 讀寫鎖
  • 遞歸鎖

c++中應該沒有樂觀鎖,java中有,CAS算法就是java中的。

繼續閱讀