文章字数:287,阅读全文大约需要1分钟
CAS(Compare-and-Swap),比较并替换。java并发包中很多类都采用了CAS技术,当获取到的内存地址和期待的内存地址相等时才将值修改,否则将或获取到的新地址变成期望地址,并循环进行下一次判断,直到成功赋值。保证代码的原子性。
使用例子
1 | private static AtomicInteger race = new AtomicInteger(0); |
CAS缺点
- 循环时间开销可能会很大
- 只能保证一个共享变量进行原子操作
- ABA问题:一个变量在读取时是A,准备赋值时检测也是A。但是可能是从A变成B,又从B变成了A,发生过变化。
带有标记的引用类AtomicStampedReference
可以通过控制变量的版本来保证CAS的正确
AtomicStampedReference
- 循环1-1000
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19public class test1 {
private static AtomicStampedReference<Integer> integer = new AtomicStampedReference<>(0,0);
public static void main(String[] args) {
for(int i=0;i<1000;i++){
final int timeStamp = integer.getStamp();
new Thread(){
public void run() {
System.out.println("timeStamp = " + timeStamp);
while (true){
if(integer.compareAndSet(integer.getReference(),integer.getReference()+1,timeStamp,timeStamp+1)){
break;
}
}
}
}.run();
}
}
}
integer.getStamp();
获取版本号compareAndSet(预期对象,修改后,预期版本,修改后版本)
返回成功或失败,失败应该手动进入循环直到完成替换。