package cas;
import javax.annotation.security.RunAs;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @author liuYC
* @ClassName CasDemo
* @Description TODO
* @date 2021/6/15 20:56
*
* cas 适用追求高性能,同时对待部分的误差可以接受:比如aba 问题,但是这类问题,银行的相关的动账系统,肯定接受不了
* 向银行这种还是老老实实的用:sycholized 进行加锁
* 那么 synchrolized 和CAS有什么区别呢:
* 我们都知道 synchrolized的 count++ 字节码分为三部分:
* 1.取值 count:
* 2. count + 1
* 3.将 count + 1 赋值给新的 count
* CAS其实就可以当作对第三步加锁,而 synchrolized 最起码是加了散步的锁,更有可能是整个对象加锁!
* 那么怎么解决ABA问题如下
*
* 可以理解为加一个版本号!
*/
public class CasDemo {
public static AtomicInteger a = new AtomicInteger(1);
public static void main(String[] args) {
Thread main = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("main 初始值:" + a.get());
int expectnum = a.get();
int newnum = expectnum + 1;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
boolean isaccerr = a.compareAndSet(expectnum, newnum);
System.out.println("cas初始化之后的结果:" + isaccerr);
}
}, "main");
Thread other = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
a.incrementAndGet();
System.out.println("other a.incre: " + a.get());
a.decrementAndGet();
System.out.println("other a.decre:" + a.get());
}
}, "other");
main.start();
other.start();
}
}
解决 ABA问题的代码方案:A.referce
package cas;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicStampedReference;
/**
* @author liuYC
* @ClassName CasSolveDemo
* @Description TODO 解决怎么从源代码中看出来对应的参数和对应的使用的方法
*
* @date 2021/6/15 21:17
* <p>
* 解决 cas 的 ABA 问题;可以理解为加一个版本号!
* 同时我记得有一次有一个面试问的就是:Atomic底层原理是什么:但是没答出来,原来就是 CAS
*/
public class CasSolveDemo {
public static AtomicStampedReference<Integer> a = new AtomicStampedReference(new Integer(1), 1);
public static void main(String[] args) {
Thread main = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("main 初始值:" + a.getReference());
int expectReference = a.getReference();
int newReference = expectReference + 1;
int expectstamp = a.getStamp();
int newnumstamp = expectstamp + 1;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
boolean isaccerr = a.compareAndSet(expectReference, newReference, expectstamp, newnumstamp);
System.out.println("cas初始化之后的结果:" + isaccerr);
}
}, "main");
Thread other = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
a.compareAndSet(a.getReference(), (a.getReference() + 1), a.getStamp(), (a.getStamp() + 1));
System.out.println("other a.incre: " + a.getReference());
a.compareAndSet(a.getReference(), (a.getReference() - 1), a.getStamp(), (a.getStamp() + 1));
System.out.println("other a.decre:" + a.getReference());
}
}, "other");
main.start();
other.start();
}
}