jdk之原子类AtomicXXXX

假设你已经阅读并理解和《jdk原子类AtomicXXXX(预备篇)》,基于以上的理解,现在我们一起来研读jdk原子类。

jdk原子类的实现方式总体很类似,因此我们选择一个比较具有代表性的AtomicLong来研读,学习就是要做到一通百通。

AtomicLong是什么

AtomicLong它提供了一些原子性的操作来操作Long类,十分适合在多线程、高并发情况下使用。

对Long的操作,不使用AtomicLong可不可以,答案是肯定的,不过我们在写代码时比较麻烦,通常做法是使用synchronized或者Lock来实现,性能还不一定是最好的,所以最优的选择肯定是使用AtomicLong(jdk8之前是最优的,jdk8后提供了一个封装类LongAdder,在锁竞争激烈的情况下,他的性能更优,《LongAdder与AtomicLong》中有详细介绍 )


1:初始化VALUE变量。通过unsafe.objectFieldOffset方法获取value内存地址相对于对象内存地址的偏移量


2:AtomicLong的value值。请注意value被volatile修饰,修饰的作用能够保证该对象的值在多线程间是可见的。但是该修饰将使得JVM的优化失效,所以不是必须情况,不乱使用AtomicXXXX类型类。(volatile的英文意思是可变的,不稳定。因为标明是可变不稳定的,线程在每次读取该值时候,都要到内存重新获取,不以高速缓存的为准)


3:lazySet修改的值不会对其他线程立即可见,在不需要让共享变量的修改立刻让其他线程可见的时候,以设置普通变量的方式来修改共享状态,可以减少不必要的内存屏障,从而提高程序执行的效率。


4:CAS方式返回旧值,设置新值


5:CAS指的就是就该方法,该方法执行的逻辑是比较替换,valueOffset值和expext做对比,一致则赋予update值,返回true,否则返回false


6:weakCompareAndSet的理解需要和CompareAndSet对照。

它们都是有条件的修改程序的方法。这两个method 都要取用两个参数 —— 在method 启动时预期数据所具有的值,以及要把数据所设定成的值。method只会在变量具有预期值的时候才会将它设定成新值。如果当前值不等于预期值,该变量不会被重新赋值且method 返回false。如果当前值等于预期值会返回boolean 的true 值,在这种情况下,值会被设定成新值。这个method 的weak 形式基本上也是一样,但是少了一项保证:如果method 返回的是false 值(虚假冲突),该变量不会被变动,但是这并不表示现有值不是预期值。这个method 不管初始值是否为预期值都可能会无法更新该值。
 

7:在高并发下为了保证获取的一个数据是最新的,而不是过期的失效数据,此处采用自旋锁(CLH)的方式做保证,只有prev是最新的值时,才执行替换


8:该情况类似getAndUpdate,只是传入的运算行数不一致而已。LongBinaryOperator只是一个接口而已,使用者可以继承实现相关接口逻辑做扩展


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值