1. 程式人生 > 實用技巧 >Java 多執行緒 - 用CAS方式獲取鎖的,都是樂觀鎖麼?

Java 多執行緒 - 用CAS方式獲取鎖的,都是樂觀鎖麼?

總結

先丟擲我的結論:用CAS方式獲取鎖的,並非都是樂觀鎖。

我們在Java裡使用的各種鎖,幾乎全都是悲觀鎖。synchronized從偏向鎖、輕量級鎖到重量級鎖,全是悲觀鎖。JDK提供的Lock實現類全是悲觀鎖。其實只要有“鎖物件”出現,那麼就一定是悲觀鎖。因為樂觀鎖不是鎖,而是一個在迴圈裡嘗試CAS的演算法。

那JDK併發包裡到底有沒有樂觀鎖呢?有。java.util.concurrent.atomic包裡面的原子類都是利用樂觀鎖實現的。原子類AtomicInteger的自增方法為樂觀鎖策略

為什麼網上有些資料認為偏向鎖、輕量級鎖是樂觀鎖?理由是它們底層用到了CAS?或者是把“樂觀/悲觀”與“輕量/重量”搞混了?其實,執行緒在搶佔這些鎖的時候,確實是迴圈+CAS的操作,感覺好像是樂觀鎖。

但問題的關鍵是,我們說一個鎖是悲觀鎖還是樂觀鎖,總是應該站在應用層,看它們是如何鎖住應用資料的,而不是站在底層看搶佔鎖的過程

如果一個執行緒嘗試獲取鎖時,發現已經被佔用,它是否繼續讀取資料,等後續要更新時再決定要不要重試?對於偏向鎖、輕量級鎖來說,顯然答案是否定的。無論是掛起還是忙等,對應用資料的讀取操作都被“擋住”了。從這個角度看,它們確實是悲觀鎖。