从CAS讲起,真正高性能解决并发编程的原子操作

原创申明:本文由公众号【猿灯塔】原创,转载请说明出处标注

今天呢!灯塔君跟大家讲:
在这里插入图片描述

一.原子性操作

原子性操作:原子性在一个操作是不可中断的,要么全部执行成功要么全部执行失败,有着“同生共死”的感觉。及时在多个线程一起执行的时候,一个操作一旦开始,就不会被其他线程所干扰。
在这里插入图片描述
在这里插入图片描述

深入源码底层发现它的方法源于:
在这里插入图片描述
继续深入:
在这里插入图片描述
发现实际上这个方法的实现原理就是CAS。

在这里插入图片描述

二.CAS

compare and swap 比较和交换
属于硬件同步原语属于CPU指令可以直接对内存做修改处理器提供了基本内存操作的原子性保证。看一下CAS原理图:
在这里插入图片描述
CAS需要有3个操作数:内存地址N,旧的预期值E,即将要更新的目标值N。

CAS指令执行时,当且仅当内存地址V的值与预期值A相等时,将内存地址V的值修改为B,否则就什么都不做。整个比较并替换的操作是一个原子操作。

首先读取开始变量值N,存入变量E,然后在进行++操作,计算后的结果值存入变量V ,

然后在将E值写回,跟N值进行比较,如果此时E值与N值是一致,则这个操作直接结束,否则就要继续从开始部分重来一次,所以CAS也被成为自旋锁,或者说无锁。

JVM提供了一个工具类 Unsafe

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

如下就是代码演示:
在这里插入图片描述

三.ABA问题

ABA问题的根本在于cas在修改变量的时候,无法记录变量的状态,比如修改的次数,是否修改过这个变量。这样就很容易在一个线程将A修改成B时,另一个线程又会把B修改成A,造成casd多次执行的问题。

解决方案:AtomicStampReference

AtomicStampReference在cas的基础上增加了一个标记stamp,使用这个标记可以用来觉察数据是否发生变化,给数据带上了一种实效性的检验。它有以下几个参数:

//参数代表的含义分别是 期望值,写入的新值,期望标记,新标记值

publicbooleancompareAndSet(Vexpected,VnewReference,intexpectedStamp,intnewStamp);

public V getRerference();

public int getStamp();

publicvoidset(VnewReference,int newStamp);

代码我就不演示了~ 希望这篇文章对各位有帮助吧!

365天干货不断,可以微信搜索「 猿灯塔」第一时间阅读,回复【资料】【面试】【简历】有我准备的一线大厂面试资料和简历模板

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值