CAS的缺點和問題解決
在並發編程中CAS的缺點和問題,如ABA問題,自旋鎖消耗問題、多變量共享一致性問題
ABA:
問題描述:線程t1將它的值從A變為B,再從B變為A。同時有線程t2要將值從A變為C。但CAS檢查的時候會發現沒有改變,但是實質上它已經發生了改變 。可能會造成數據的缺失。
解決方法:CAS還是類似於樂觀鎖,同數據樂觀鎖的方式給它加一個版本號或者時間戳,如AtomicStampedReference
自旋消耗資源:
問題描述:多個線程爭奪同一個資源時,如果自旋一直不成功,將會一直占用CPU。
解決方法:破壞掉for死循環,當超過一定時間或者一定次數時,return退出。JDK8新增的LongAddr,和ConcurrentHashMap類似的方法。當多個線程競爭時,將粒度變小,將一個變量拆分為多個變量,達到多個線程訪問多個資源的效果,最后再調用sum把它合起來。
雖然base和cells都是volatile修飾的,但感覺這個sum操作沒有加鎖,可能sum的結果不是那么精確。
public long sum() {
Cell[] as = cells; Cell a;
long sum = base;
if (as != null) {
for (int i = 0; i < as.length; ++i) {
if ((a = as[i]) != null)
sum += a.value;
}
}
return sum;
}
多變量共享一致性問題:
解決方法: CAS操作是針對一個變量的,如果對多個變量操作,1. 可以加鎖來解決。2 .封裝成對象類解決。