CAS ABA问题解决

CAS(compare and swep)比较然后交换

通常需要三个参数,一个是预期值,一个是当前值,一个是替换值

逻辑是 当 预期值 与 当前值 相等时,替换值进行替换,同时返回true。

ABA问题

因为CAS需要在操作值的时候,检查值有没有发生变化,如果没有发生变化则更新,但是如果一个值原来是A,变成了B,又变成了A,那么CAS进行检查时会发现它的值没有发生变化,但是实际上已经发生了变化。

譬如

 对于这个问题Atomic包里面自带的AtomicStampedReference类能够解决这个问题,解决思路就是对于一个值设置一个版本号,更改一次改变一次,进行CAS时不光需要核对Value还要核对版本号。

代码:

 1 package thread;
 2 
 3 import java.util.concurrent.TimeUnit;
 4 import java.util.concurrent.atomic.AtomicStampedReference;
 5 
 6 /**
 7  * 解决ABA问题,atomic包里面自带的AtomicStampedReference类
 8  */
 9 public class AtomicStampedReferenceDemo {
10     public static AtomicStampedReference<Integer> atomicStampedReference =
11             new AtomicStampedReference<Integer>(100,0);
12 
13     public static void main(String[] args) {
14         Thread intT1 = new Thread(new Runnable() {
15 
16             @Override
17             public void run() {
18                 try {
19                     TimeUnit.SECONDS.sleep(1);
20                 } catch (InterruptedException e) {
21                     e.printStackTrace();
22                 }
23                 atomicStampedReference.compareAndSet(100,101,
24                         atomicStampedReference.getStamp(),
25                         atomicStampedReference.getStamp() + 1);
26                 atomicStampedReference.compareAndSet(101,100,
27                         atomicStampedReference.getStamp(),
28                         atomicStampedReference.getStamp() + 1);
29             }
30         });
31         Thread intT2 = new Thread(new Runnable() {
32 
33             @Override
34             public void run() {
35                 int stamp = atomicStampedReference.getStamp();
36                 System.out.println(stamp);//0
37                 try {
38                     //相当于Thread.sleep,能够自定义单位
39                     TimeUnit.SECONDS.sleep(2);
40                 } catch (InterruptedException e) {
41                     e.printStackTrace();
42                 }
43                 Boolean b = atomicStampedReference.compareAndSet(100, 101,
44                        stamp,
45                         stamp + 1);
46                 System.out.println(b);//false
47                 System.out.println(atomicStampedReference.getReference());//100
48             }
49         });
50 
51 
52         intT1.start();
53         intT2.start();
54     }
55 
56 }
 

猜你喜欢

转载自www.cnblogs.com/frank9571/p/12385347.html