Volatile是什么,CAS是什么:

一句话说明白:啥是Volatile,其实就是轻量级的同步机制:保证可见性,不保证原子性,禁止指令重排。

 记住:Volatile就是乞丐版的synchronizid	。

我们主要从三部分理解volatile:保证可见性,不保证原子性,禁止指令重排。

  • 保证可见性和禁止指令重排的理解:

volatile实现禁止指令重排优化,从而避免多线程环境下程序出现乱序执行的现象。
先了解一个概念,内存屏障又称内存栅栏,是一个CPU指令,它的作用有两个:
一是保证特定操作的执行顺序
二是保证某些变量的内存可见性(利用该特性实现volatile的内存可见性)

由于编译器和处理器都能执行指令重排优化。如果在指令间插入一条Memory Barrier则告诉编译器和CPU,不管什么指令都不能和这条Memory Barrier指令重新排序,也就是说
通过插入内存屏障禁止在内存屏障前后的指令执行重排序优化。内存屏障另外一个作用是强制刷出各种CPU的缓存数据,因此任何CPU上的线程都能读取到这些数据的最新版本。

  • 不保证原子性的理解:(了解一下JMM)

在这里插入图片描述
主内存的介绍:硬件上指的是我们日常用的比如8G 内存条。
在这里插入图片描述
在这里插入图片描述
解决原子性:用原子操作的类:比如AtomicInteger。

CAS是什么:
解决原子性:用原子操作的类:比如AtomicInteger。那么AtomicInteger的底层原理是什么,底层原理其实就是cas.
CAS 就是比较并交换。
AtomicInteger.compareAndSet()-----底层是compareAndSwap.
CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。
怎么理解:根据JMM*(Java内存模型)来看,设主物理内存中的变量temp的内存值是V,线程一的预期值为A,其实就是私有线程中的主内存的线程副本temp的缓存值为A,线程一想要把temp的值V修改为新值B,此时对比V是否等于A,如果相等,说明没有其他线程对主内存中的值进行修改,那么可以进行修改,否则就说明其他线程对主内存中的值进行了修改,那么线程一不能进行直接修改,想要修改,必须重新把V的值读入自己的缓存中,然后再重新进行下一轮比较。以此类推

底层原理:
atomicInter.getAndIncrement()底层是unsafe.getAndAddInt(this,valueoffset,i)
1.Unsafe
是CAS的核心类,由于Java方法无法直接访问底层系统,需要通过本地(native)方法来访问,Unsafe相当于一个后门,基于该类可以直接操作特定内存的数据。
Unsafe类存在于sun.misc包中,其内部方法操作可以像C的指针一样直接操作内存,因为Java中CAS操作的执行依赖于Unsafe类的方法。

注意Unsafe类中的所有方法都是native修饰的,也就是说Unsafe类中的方法都直接调用操作系统底层资源执行相应任务。

2.变量valueOffset,表示该变量在内存中的
偏移地址,因为Unsafe就是根据内存偏移地址获取数据的。

3.变量value用volatile修饰,保证了多线程之间的内存可见性。
总结来看,CAS靠的是汇编指令中的CPU原语操作来保证原子性。

CAS的缺点:
1、 循环时间长开销大:如果CAS失败,会一直进行尝试。如果CAS长时间一直不成功,可能会给CPU带来很大的开销。不断自旋
2、 只能保证一个共享变量的原子操作:当对一个共享变量执行操作时,我们只能使用循环CAS的方式来保证原子操作,但是,对多个共享变量操作时,循环CAS就无法保证操作的原子性,这个时候就可以用锁来保证原子性。
3、 可能会引发ABA问题:
ABA问题其实就是狸猫换太子;产生原因:CAS算法实现一个重要前提需要取出内存中某时刻的数据并在当下时刻比较并替换,那么在这个时间差类会导致数据的变化。

比如说:主存的内存值为5,现在有两个线程:T1,T2。初始情况,T1,T2都从主内存中拷贝5,假设T1,两秒钟对自身5修改一次,T2十秒钟对自身5修改。现在T1线对自身5修改为2,之后写入主内存,此时主内存为2,T1为2,T2中的值为5,又过了两秒T1又把2改为5,重新写入主内存,到了第十秒,T2来读主内存比较,发现还是5,就以为主内存的值没有被其他线程动过。其实这种以为是错误的。

解决ABA问题用原子时间戳引用,用AtomicStampledReference,就是每次改变都加一个时间戳,CAS过程中不仅要比较内存值和预测值还要比较时间戳。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值