首先要明白cas解决的问题,它是乐观锁的一种解决方式,都是多线程并发情况下解决数据线程按全问题的一种手段-----无锁并发
结合CAS和volatile 可以实现无锁并发,适用于线程数少、多核CPU的场景下。(cas要配合volatile使用,因为多线程操作下,为了保证线程修改完数据后,其他线程立刻可见)
public final boolean getAndSet(boolean newValue) {
boolean prev;
do {
prev = get();
} while (!compareAndSet(prev, newValue));
return prev;
}
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicReference;
public class AtomicTest {
static AtomicReference<String> atomicReference=null;
public AtomicTest(String list){
this.atomicReference=new AtomicReference<>(list);
}
public static void main(String[] args) throws InterruptedException {
AtomicTest atomicTest = new AtomicTest("");
CountDownLatch countDownLatch = new CountDownLatch(100);
ExecutorService executorService = Executors.newFixedThreadPool(200);
for (int i = 1; i <=100 ; i++) {
executorService.submit(()->{
try{
atomicTest.update(String.valueOf(1));
}finally {
countDownLatch.countDown();
}
});
}
countDownLatch.await();
executorService.shutdown();
System.out.println(atomicReference.toString());
System.out.println(atomicReference.get().length());
}
public void update(String H){
AtomicTest.atomicReference.updateAndGet(g->{
return g+H;
});
}
}
注意它们里边只有使用了compareAndSet才能保证操作的原子性和线程安全
AtomicStampedReference--上边的AtomicReference存在一个问题,比如现在有一个String类型,当前线程首先获取到了a,但是现在有其他线程先把a改成了b,又把b改成了a,如果我们要求,只要其他线程修改过这个值,我们就要修改失败,那么AtomicReference是没办法实现的,在AtomicStampedReference并没有帮我们实现类似于updateAndGet这样的方法,需要我们自己通过compareAndSet实现,见如下代码
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicStampedReference;
public class AtomicTest {
static AtomicStampedReference<String> atomicReference=null;
public AtomicTest(String list){
this.atomicReference=new AtomicStampedReference<>(list,0);
}
public static void main(String[] args) throws InterruptedException {
AtomicTest atomicTest = new AtomicTest("");
CountDownLatch countDownLatch = new CountDownLatch(100);
ExecutorService executorService = Executors.newFixedThreadPool(200);
for (int i = 1; i <=100 ; i++) {
executorService.submit(()->{
try{
atomicTest.update(String.valueOf(1));
}finally {
countDownLatch.countDown();
}
});
}
countDownLatch.await();
executorService.shutdown();
System.out.println(atomicReference.getReference());
System.out.println(atomicReference.getReference().length());
}
public void update(String H){
while (true){
//获取最新值
String reference = atomicReference.getReference();
//获取版本号
int stamp = atomicReference.getStamp();
if (atomicReference.compareAndSet(reference,reference+H,stamp,stamp+1)){
break;
}
}
}
}