juc之volatile和CAS算法

大家推荐个靠谱的公众号程序员探索之路,大家一起加油,这个公众号已经接入图灵《juc之volatile和CAS算法》 ​  

之前一直有疑惑,volatile关键字时内存可见的为什么改值的时候还得处理并发问题,今天终于搞懂了

1.volatile关键字能 保证 每次读取的是最新的   但是如果有多个线程同时改变 值 还是不能保证线程安全

volatile缺点:

1.volatile 不具备“互斥性”   
2.volatile  不能保证变量的原子性

2.CAS(compare-and-swap)是一种硬件对并发的支持,针对多处理器操作而设计的处理器中的一种特殊指令,用于管理对共享数据的并发访问。

CAS是一种无锁的非阻塞算法的实现。
CAS包含了3个操作数
需要读写的内存值V
进行比较的值A
拟写入的新值B

当且仅当V的值等于A时,CAS通过原子方式用新值B来更新V的值,否则不会执行任何操作。

spring cloud 中ribbon轮询算法中控制并发就是用的CAS算法

《juc之volatile和CAS算法》

当然里面用的java提供的原理变量AtomicInteger,  在java.util.concurrent.atomic包下java提供了很多常用的原子变量

 3.CAS缺点

CAS的缺点:
CAS虽然很高效的解决了原子操作问题,但是CAS仍然存在三大问题。

循环时间长开销很大。
只能保证一个共享变量的原子操作。
ABA问题。
循环时间长开销很大:
我们可以看到getAndAddInt方法执行时,如果CAS失败,会一直进行尝试。如果CAS长时间一直不成功,可能会给CPU带来很大的开销。

只能保证一个共享变量的原子操作:
当对一个共享变量执行操作时,我们可以使用循环CAS的方式来保证原子操作,但是对多个共享变量操作时,循环CAS就无法保证操作的原子性,这个时候就可以用锁来保证原子性。

什么是ABA问题?ABA问题怎么解决?
如果内存地址V初次读取的值是A,并且在准备赋值的时候检查到它的值仍然为A,那我们就能说它的值没有被其他线程改变过了吗?

如果在这段期间它的值曾经被改成了B,后来又被改回为A,那CAS操作就会误认为它从来没有被改变过。这个漏洞称为CAS操作的“ABA”问题。Java并发包为了解决这个问题,提供了一个带有标记的原子引用类“AtomicStampedReference”,它可以通过控制变量值的版本来保证CAS的正确性。因此,在使用CAS前要考虑清楚“ABA”问题是否会影响程序并发的正确性,如果需要解决ABA问题,改用传统的互斥同步可能会比原子类更高效。
 

    原文作者:JUC
    原文地址: https://blog.csdn.net/yueloveme/article/details/85037950
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞