java 原子类详解

什么是原子类?

就是可以保证线程安全的原子操作的数据类型。

有什么作用?

原子类的作用和锁类似,为了保证并发情况下的线程安全。原子类和锁相比,要比锁的粒度更细,效率更高。
在这里插入图片描述

下面我们就逐个介绍以上6个原子类型:

Atomic*基本类型原子类:

这里我们就以AtomicInteger为例做介绍其常用方法:

  • public final int get() //获取当前的值
  • public final int getAndSet(int newValue) //获取当前的值
  • public final int getAndIncrement() //获取当前的值,并自增
  • public final int getAndDecrement() //获取当前的值,并自减
  • public final int getAndAdd(int delta) //获取当前的值,并加上预期的值
  • boolean compareAndSet(int expect, int update) //如果输入的数值等于预期值,则以原子方式将该值设置为输入值(update)

Atomic*Reference引用类型原子类

  • AtomicReference:AtomicReference类的作用,和AtomicInteger并没有本质区别,AtomicTnteger
  • 可以让一个整数保证原子性,儿AtomicReference可以让一个对象保证原子性,当然,AtomicReference的功能明显比AtomicTnteger强,因为一个对象里可以包含很多属性。用法和AtomicTnteger类似。

在这里插入图片描述

AtomicIntegerFieldUpdater对普通变量进行升级

  • AtomicIntegerFieldUpdater:把普通变量升级为具有原子功能
  • 使用场景:偶尔需要一个原子get-set操作
  • 注意点:
    1.可见范围:变量如果是private修饰,则无法升级
    2.不支持static

Adder累加器

  • 累加器是java 8引入的,相对是比较新的一个类
  • 高并发下LongAdder比AtomicLong效率高,不过本质是空间换时间
  • 竞争激烈的时候,LongAdder把不同线程对应到不同的Cell上进行修改,降低了冲突的概率,是多段锁的理念,提高了并发性。

在这里插入图片描述
上图为AtomicLong的数据在不同线程中获取的过程:
当一个AtomicLong的数据变化时,会先把数据从本地缓存区flush到共享缓存区,然后别的线程读取的时候,会先从共享缓存区refresh到本地缓存区,这样才能获取到AtomicLong的最新数据。

  • 很明显,这种操作虽然保证了数据的安全性,但是在高并发情况下,大量的flush、refresh操作会严重影响效率。而Adder累加器则是在此基础上进行了优化改进。

这里是引用
如图中所示,第一个线程的计数器数值,也就是ctr为1的时候,可能线程2的计数器ctr的数值已经是3了,他们之间不存在竞争关系,所以在加和的过程中,根本不需要同步机制,也不需要刚才的flush和refresh操作。这里也没有一个公共的counter来给线程统一计数。

改进和原理

  • LongAdder引入了分段累加的概念,内部有一个base变量和一个Cell[]数组共同参与计数。
  • base变量:竞争不激烈,直接累加到该变量上
  • Cell[]数组:竞争激烈,各个线程分散累加到自己的槽Cell[i]中

这里是引用
上图为LongAdder的sum方法源码,我们可以看到,sum方法是没有加锁的,因此在求和的时候如果Cell数组被修改,则可能会出现数值不准确的情况。

对比AtomicLong和LongAdder

  • 在低争用下,在AtomicLong和LongAdder这两个类具有相似的特征。但是在竞争激烈的情况下,LongAdder的预期吞吐量要高得多,但要消耗更多的空间
  • LongAdder适合的场景是统计求和计数的场景,而且LongAdder基本只提供了add方法,儿AtomicLong还具有cas方法。

Accumulator累加器

Accumulator和Adder非常相似,Accumulator就是一个更通用版本的Adder
在这里插入图片描述
使用场景:大量数字计算,并且高并发场景下

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值