CAS机制总结

  • CAS机制 
  • CAS和synchronized 区别,场景,有缺点 ???
  • CAS底层实现、ABA问题场景、解决办法

场景:公共内存值v=10,在加锁的情况下,线程a,b分别对10进行 5次++ 的操作,最后结果20。
问题是如果不加锁,a得到内存值10在进行++操作时,b也获得内存值10进行++操作。
此时就会出现结果<20的情况。为什么???不是可以重试的吗???

一、

CAS机制:compare and swap(比较和替换)

CAS三个操作数:V(内存值) ,A(旧的预期值)  和 B(新值)

CAS的使用场景:juc下 lock、atomic 操作 ???juc???
CAS乐观锁(循环内自旋???),原理:A=获得内存值,B=对A进行累加操作后的值。更新内存值V为B的时候先将V和A对比,
如果相等,那么V替换B退出循环,如果不相等,重新获得内存值,进行操作。???
此套流程如何保证内存值是最新的? 详见volatile原理???
此套流程如何保证V,A比较B替换V时是原子操作? CAS底层用unsafe直接访问底层操作系统,做了硬件级别的原子操作。???

二、

synchronized:悲观锁,当synchronized锁住后,其它线程处于blocking状态(阻塞),当其余线程获得锁后,
会进入runnable状态,这个过程中涉及到操作系统用户模式和内核模式的转换,代价比较高。???
并发量很高的话,synchronized还是比较适合的。

并发量很少的情况下,用synchronized,就不合适,关键在于影响性能。

 

synchronized关键字会让没有得到锁资源的线程进入BLOCKED状态,而后在争夺到锁资源后恢复为RUNNABLE状态,这个过程中涉及到操作系统用户模式和内核模式的转换???,代价比较高。

 

尽管JAVA 1.6为synchronized做了优化,增加了从偏向锁到轻量级锁再到重量级锁的过度???,但是在最终转变为重量级锁之后,性能仍然比较低。所以面对这种情况,我们就可以使用java中的“原子操作类”???什么是原子操作类???

所谓原子操作类,指的是java.util.concurrent.atomic包下,一系列以Atomic开头的包装类。如AtomicBoolean,AtomicUInteger,AtomicLong。它们分别用于Boolean,Integer,Long类型的原子性操作。

使用AtomicInteger之后,最终的输出结果同样可以保证是200。并且在某些情况下,代码的性能会比synchronized更好。参照: 

什么是CAS机制?  https://blog.csdn.net/qq_32998153/article/details/79529704 

而Atomic操作类的底层正是用到了“CAS机制”。

CAS是英文单词Compare and Swap的缩写,翻译过来就是 比较 并 替换 。(理解:先比较,符合预期则替换,若不符合预期则不替换。)

CAS机制中使用了3个基本操作数:内存地址V,旧的预期值A,要修改的新值B。

更新一个变量的时候,只有当变量的预期值A和内存地址V当中的实际值相同时,才会将内存地址V对应的值修改为B。

 

从思想上来说,synchronized属于悲观锁,悲观的认为程序中的并发情况严重,所以严防死守,CAS属于乐观锁,乐观地认为程序中的并发情况不那么严重,所以让线程不断去重试更新???

在java中除了上面提到的Atomic系列类???,以及Lock系列类???夺得底层实现,甚至在JAVA1.6以上版本,synchronized转变为重量级锁之前,也会采用CAS机制。 

三、

CAS优点:如一描述在并发量不是很高时CAS机制会提高效率。???怎么提出合理的解释???


CAS缺点:
1、cpu开销大,在高并发下,许多线程,更新一变量,多次更新不成功,循环反复,给cpu带来大量压力。??? 会通过 自旋(更新不成功-先阻塞-再重新尝试更新) 来更新???
2、CAS机制所保证的只是一个变量的原子性操作,而不能保证整个代码块的原子性。比如需要保证3个变量共同进行原子性的更新,就不得不使用synchronized了。

3、ABA问题: CAS -- ABA问题的解决方案

参考文档: 什么是CAS机制?  https://blog.csdn.net/qq_32998153/article/details/79529704   , https://www.cnblogs.com/DivineHost/p/9270109.html 

原文地址:https://www.cnblogs.com/william-dai/p/10895161.html