线程安全之原子操作

本文主要内容

1、原子操作定义

2、原子操作的方式(同步锁机制、cas机制、原子操作类)

3、总结


一、原子操作定义

    1、定义:

     原子操作可以是一个步骤,也可以是多个操作步骤,但是其顺序不可以被打乱,也不可以被切割而执行其中的一部分,原子操作具有不可中断性。它的核心特征是将整个操作视为一个整体。

    2、实例:        

     上面的截图中i++操作存在多个操作,在多线程环境下会出现竞态条件,线程不安全,需要转变为原子操作才能安全。下面将介绍操作操作的方式。


二、原子操作方式

      1、同步锁机制:

   2、cas机制

     定义:cas机制:cas操作需要输入两个数值,一个旧值A和一个新值B,在操作期间先比较下旧值有没有发生变化,如果没有发生变化,才交换成新值,发生了变化则不交换。

  java中sun。misc。Unsafe类提供了一些方法实现cas。

    实例:

     

   3、原子操作封装类

    (1)基础版: Java中提供了一些原子操作封装类,封装了cas机制的底层代码,使得用户使用起来更加方便。

     例如:

      AtomicBoolean:原子更新布尔类型;AtomicInteger:原子更新整型;AtomicLong:原子更新长长整型。

     AtomicIntegerArray:原子更新整型数组里的元素。 AtomicLongArray:原子更新长整型数组里的元  素。         AtomicReferenceArray:原子更新引用数组里的元素。

    AtomicIntegerFieldUpdater:原子更新整型字段里的更新器。    AtomicLongFieldUpdater:原子更新长整型字段里的更新器。    AtomicReferenceFieldUpdater:原子更新引用类型里的字段。

    AtomicReference:原子更新引用类型。    AtomicStampedReference:原子更新带有版本号的引用类型。    AtomicMarkableReference:原子更新带有标记位的引用类型。

   实例:下面介绍AtomicInteger类的实例

    


    (2)更新版: 1.8版本的jdk还更新了四个原子操作的封装类。

      更新器:DoubleAccumulator、LongAccumulator

      计数器:DoubleAdder、LongAdder

      实例1:介绍LongAccumulator类使用代码    

实例2:下面是LongAdder类的使用代码

计数器增强版,高并发下性能更好,频繁更新但不太频繁读取的汇总统计信息时使用,分成多个操作单元,不同线程更新不同的单元,只有需要汇总的时候才计算所有单元的操作


三、总结

cas的弊端:
1、cpu开销大,在高并发下,许多线程,更新一变量,多次更新不成功,循环反复,给cpu带来大量压力。

2、只是一个变量的原子性操作,不能保证代码块的原子性。

3、ABA问题

ABA问题:内存值V=100;

threadA 将100,改为50;

threadB 将100,改为50;

threadC 将50,改为100;

场景:小牛取款,由于机器不太好使,多点了几次全款操作。后台threadA和threadB工作,

此时threadA操作成功(100->50),threadB阻塞。正好牛妈打款50元给小牛(50->100),

threadC执行成功,之后threadB运行了,又改为(100->50)。

牛气冲天,lz钱哪去了???

如何解决aba问题:

对内存中的值加个版本号,在比较的时候除了比较值还的比较版本号。

java:AtomicStampedReference就是用版本号实现cas机制。





    

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 数据一致性问题 有以下一段代码 运行结果为,与预期的输出 20000 不一样 如图,线程 T1 和 T2 都获取到...
    佐蓝Gogoing阅读 519评论 0 0
  • 当程序更新一个变量时,如果多线程同时更新这个变量,可能得到期望之外的值,比如变量i=1,A线程更新i+1,B线程也...
    Steven1997阅读 535评论 0 0
  • 张东辉,讲师七期坚持原创分享第863天(2020.1.12) 昨天晚上到家,已经是九点多。孩子先我一步已经到家。一...
    星悦传奇阅读 146评论 0 1
  • 问题 输入两个字符串a和b,字符串内容为二进制数字,求两个字符串相加的结果,加法计算方法以二进制方式计算,并返回对...
    北子萌阅读 500评论 0 0
  • 每晚躺床上都觉得自己昏昏欲睡,当然也确实很快睡着!可是半夜老是醒过来,醒过来又睡不着,睁着眼睛看手机,挣扎到天快亮...
    将归阅读 35评论 0 0