JUC多线程及高并发8-----CAS
面试题笔记3
其中var1 ------Atomicinteger 对象本身
var2---------该对象值得引用地址
var4---------需要变动的数量
var5----------是用过var1 var2找出的主内存中真实的值
用该对象当前的值 与var5比较
如果相同,更新var5+var4并且返回true
如果不同,继续取值然后再比较,直到更新完成
假设线程A和线程B俩个线程同时执行getAndAddInt操作(分别跑在不同CPU上)
1.AtomicInteger里面的value原始值为3,即主内存中AtomicInteger的value为3,根据JMM模型,线程A和线程B各自持有一份值为3的value的副本分别到自己的工作内存。
2.线程A通过getintvolatile(var1,var2)拿到value值3,这时线程A被挂起
3.线程B也通过getintvolatile(var1,var2)拿到value值3,此时刚好线程B没有挂起,并执行compareAndSwapInt方法比较内存值也是3,成功修改内存值4,线程B打完收工,一切OK
4.这时线程A恢复,执行compareAndSwapInt方法比较,发现自己手里的值数字3和主内存的值数字4不一致,说明该值已经被其他线程抢先一步修改过了,那A线程本次修改失败,只能重新读取重新来一遍了。
5.线程A重新获取value值,因为变量value被volatile修饰,所以其他线程对他的修改,线程A总是能看到,线程A继续执行
compareAndSwapInt进行比较替换,直到成功。
CAS --(CompareAndSwap)
比较当前工作内存中的值,和主内存中的值,如果相同则执行规定操作,
否则继续比较直到主内存和工作内存中的值一致为止
CAS应用
CAS有三个操作数,内存值V,旧的预期值A,要修改的更新值B
当且仅当预期值A和内存值V相同,将内存值V改为B,否则什么都不做。
CAS缺点:
循环时间长,开销很大
getandaddint方法执行有do while 线程如果不成功,就会一直转,不会跳出循环,时间长了,开销会很大。
只能保证一个共享变量的原子操作
引出来ABA问题