一、CAS介紹
CAS(Compare and Swap),即比較-交換操作,是一種原子操作。原子操作是指不可中斷的一個或一系列操作。這個操作被看做是一個整體,不可能被線程調度機制打斷,保證了並發安全性。其中CAS是一種基於硬體實現的操作,可以實現不加鎖的並發安全。
CAS一般包括三個操作數:內存位置(V)、預期原值(A)和新值(B)。如果內存位置的值與預期原值相匹配,那麼處理器會自動將該位置值更新為新值。否則,處理器不做任何操作。整個比較和交換操作是一個原子操作。
二、CAS的應用
CAS主要應用於多線程並發操作中,例如在Java中,常用的Atomic系列類,就是使用CAS實現的原子操作類,如下所示:
public class AtomicInteger { private volatile int value; public AtomicInteger(int value) { this.value = value; } public final int get() { return value; } public final int getAndIncrement() { for (;;) { int current = get(); int next = current + 1; if (compareAndSet(current, next)) return current; } } public final boolean compareAndSet(int expect, int update) { return unsafe.compareAndSwapInt(this, valueOffset, expect, update); } }
上面代碼中的getAndIncrement()方法就是使用CAS實現的原子操作,其實現方式可以簡單描述為:
- 獲取當前值(current)
- 計算新的值(next)
- 使用CAS更新值,如果更新成功,則返回當前值
- 如果更新失敗,則重新獲取當前值進行下一次操作
三、CAS的優缺點
優點
- 無鎖化並發編程,避免了鎖的開銷
- 確保了並發條件下的數據一致性和正確性
- 可以減少內存的使用,提高內存效率
- 可擴展性比鎖高,可以有效避免死鎖問題
缺點
- CAS操作的ABA問題:如果位置V一開始是A,後來被改為B,然後又被改回為A,那麼CAS會認為它從來沒有被修改過。解決方式可以加上版本號,每次修改都會將版本號+1。
- CAS操作只能保證一個共享變數的原子操作,對多個共享變數的操作必須加鎖
- CAS操作失敗的開銷比較大,包括循環時間、CPU消耗等資源的消耗,如果CAS機制適用的情景是非常重要的
四、CAS的實現
下面給出一個CAS的簡單實現,用於說明CAS的原理:
public class ThreadSafeCounter { private volatile int count; public int getCount() { return count; } public void increment() { int oldValue = count; while (!compareAndSet(oldValue, oldValue + 1)) { oldValue = count; } } public boolean compareAndSet(int oldValue, int newValue) { if (count == oldValue) { count = newValue; return true; } return false; } }
上面代碼中的increment()方法使用了CAS實現的原子操作,其實現方式可以簡單描述為:
- 獲取當前值oldValue
- 如果使用CAS更新值失敗,則重新獲取當前值oldValue
- 重複執行第二步,直到更新成功
五、總結
CAS作為一種基於硬體實現的操作,可以實現不加鎖的並發安全,常見的應用場景是多線程並發操作。雖然CAS有其優勢和缺點,但是在特定的場景下,可以有效地提高代碼的效率和性能。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/308503.html