JAVA CAS以及ABA问题解决方案

在计算机科学中,比较和交换(Conmpare And Swap)是用于实现多线程同步的原子指令。 它将内存位置的内容与给定值进行比较,只有在相同的情况下,将该内存位置的内容修改为新的给定值。 这是作为单个原子操作完成的。 原子性保证新值基于最新信息计算; 如果该值在同一时间被另一个线程更新,则写入将失败。 操作结果必须说明是否进行替换; 这可以通过一个简单的布尔响应(这个变体通常称为比较和设置),或通过返回从内存位置读取的值来完成(摘自维基本科)

下面看代码

AtomicInteger atomicInteger = new AtomicInteger(1);

atomicInteger.getAndIncrement();

atomicInteger.compareAndSet(atomicInteger.getAndIncrement(), 6)

compareAndSet(V,E,U) V是内存的值,E是预期的值,U是要修改的值,通过比较替换实现无锁的操作,其实是乐观锁,不过CAS有一个ABA的问题。

 

 

2.ABA问题

比如有2个线程1,2 如果内存中的值为X,1线程从内存中获取到X,并且想设置值为A,线程2也从内存中获取到X,并且线程2先执行设置内存的值为B,然后在设置为X,此时1线程获取到的值X,跟内存中对比的值X结果是一样的,之后线程1就可以设置内存的值为A,此时觉得没什么问题,但是线程2已经修改过这个值了,尽管线程1的操作成功但是不代表没有问题,至于会有什么问题,跟链表有关系,自行baidu吧

解决方案:

java 提供两种解决方案

1。AtomicStampedReference是带时间戳的

AtomicStampedReference atomicStampedReference1 = new AtomicStampedReference(100, stamp);

System.out.println(atomicStampedReference1.compareAndSet(100, 2, stamp+1, stamp+1));

System.out.println(atomicStampedReference1.getReference());

2。是带boolean类型的

AtomicMarkableReference atomicMarkableReference = new AtomicMarkableReference(100,true);

System.out.println(atomicMarkableReference.compareAndSet(100, 4, true, false));

System.out.println(atomicMarkableReference.getReference());

System.out.println(atomicMarkableReference.compareAndSet(100, 4, true, false));

 

 

你可能感兴趣的:(JAVA CAS以及ABA问题解决方案)