面试必备:CAS无锁机制
CAS無鎖機制原理,面試高頻問題之一,其實,日常開發中并不會直接使用CAS無鎖機制,都是通過一系列封裝好的工具類來使用,
說不定面試官不提問,都不知道有這么個東西存在。
1、能說一下你對CAS的理解嗎?
參考回答:
通常我們提到保證多線程安全,會想到三種方式,一是使用Synchronize關鍵字,但是有個問題就是,使用了Synchronize加鎖后的多線程相當于串行,執行效率并不是太高,所以在高并發場景下,使用第二種方式Lock鎖,Lock鎖要比使用Synchronize關鍵字在性能上有極大的提高,其實Lock鎖底層就是通過AQS+CAS機制實現的;第三種方式就是使用Java并發包下的Atomic「e淘米客」原子操作類,使用了原子類后就不需要使用Synchronize關鍵字或者是Lock加鎖也是線程安全的,原子類的底層就是基于CAS無鎖算法實現的。
CAS 比較后再交換。CAS有三個操作數,舊值A,新值B,以及需要讀取的內存值V,在更新一個變量時,當且僅當A=V相同時,CAS才會將內存值V修改為B,否則什么都不做。
參考回答有點啰嗦了,提到了CAS的應用場景原子類的使用,但多說點顯得有丶東西
2、能說一下CAS的實現原理嗎?
參考回答
Java里的CAS是通過調用Unsafe「安sei夫」類的native方法,再由C調用CPU底層命令實現的。
如果問到Unsafe?
Unsafe 這個類是 JDK 提供的一個比較底層的類,是一個不安全的類,官方不建議開發者使用的,為啥呢?①Unsafe在未來可能被移除,也就是高版本jdk可能無法運行;②Unsafe中不少方法中必須提供內存地址和被替換對象的地址,中間會有一些計算問題,一旦出現問題就會導致jvm實例崩潰;③Unsafe中提供的直接訪問內存的方法不受jvm管理,需要手動操作,如果疏忽可能會觸發內存泄漏;
Unsafe通常用來:「額外補充,了解即可」
- 內存管理:包括分配內存、釋放內存
- 操作類、對象、變量:通過獲取對象和變量偏移量直接修改數據
- 掛起與恢復:將線程阻塞或者恢復阻塞狀態
- CAS:調用 CPU 的 CAS 指令進行比較和交換
- 內存屏障:定義內存屏障,避免指令重排序
如果你想了解加深CAS原理,那么可以敲出一個原子類變量,比如AtomicInteger,直接看一下他的源碼,找一下Unsafe是怎么大量應用的。
3、能說一下CAS的優缺點?
缺點
在并發量比較高的情況下,如果線程反復嘗試更新一個變量,卻又一直更新不成功,循環往復,會給CPU帶來很大的壓力。
只能是一個變量的原子操作,無法確保整個代碼塊的原子性,也就是在需要保證2個及以上變量共同進行原子性的更新時,就不得不使用Synchronized了
假設有一個變量 A ,經修改后變為B,然后又修改為 A,實際已經修改過了,但 CAS 可能無法感知,造成了不合理的值修改操作。
解決方案是:使用版本號,在變量前面追加上版本號,每次變量更新的時候把版本號加一,那么A-B-A 就會變成1A-2B-3A
*優點
在一般情況下,性能優先于鎖的使用。
4、最后補充
從思想上來說,Synchronized屬于悲觀鎖,悲觀地認為程序中的并發情況嚴重,所以嚴防死守。
CAS屬于樂觀鎖,樂觀地認為程序中的并發情況不那么嚴重,所以讓線程不斷去嘗試更新。
CAS和Synchronized沒有絕對的好與壞,關鍵看使用場景。在并發量非常高的情況下,反而用同步鎖更合適一些。
?
總結
以上是生活随笔為你收集整理的面试必备:CAS无锁机制的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Windows下【AxureRP】原型设
- 下一篇: 浅谈分布式锁