java中的原子类

++i 与 i++

updateAndGet()

这个方法的入参是一个IntUnaryOperator

 

这个类是一个接口类,且被@FuntionalInterface注解,说明这个接口仅仅有一个方法需要实现,即可以配合lamda表达式使用

 

最终i1的值为50,因此其中的x就是要被操作的数 ,此处仅仅是演示 *10,完全可以做复杂的运算,如果过程中x的值被其他线程修改,就继续while-true重新来。直到修改完结果,getAndUpdate同理,即下面这段逻辑。

 原子引用

可以看出和上面没有什么太大的不同之处

ABA问题 

 这是一次while的流程,prev变量记录被修改前的值,再尝试用CAS将prev修改为目标值,但是有一点,我们怎么知道已经获取到prev有没有被修改过呢,比如prev为A,然后线程2将A修改为B,此时又有线程3将B修改为A,对线程1来说,是没有发生过修改的,我的CAS操作可以完成,但是事实上变量已经被人修改过了。

只能说算一个隐患,即线程无法感知到对变量的修改 

即线程仅能判断出共享变量的值与最初的值A是否相同,不能感知到这种从A改为B又改回A的情况,如果主线程希望:

只要有其他线程【动过了】共享变量,那么自己的CAS就算失败,这时,仅仅靠比较值是不够的,还需要加入一个版本号

 AtomicStampedReference可以给原子引用加上版本号,追踪原子引用整个的变化过程,如:A -> B -> A -> C ,通过AtomicStampedReference,我们可以知道,引用变量中途被修改了几次。

但是有时候,我们并不关系引用变量被修改了几次,我们单纯的关系是否被修改过,所以就出现了AtomicMarkableReference

因为标志位不一样,因此最后的修改没有成功

但是有些时候,我们要修改的并不是引用本身,而是要修改引用里边的内容,比如我们要修改一个数组对象

原子数组

  • AtomicIntegerArray
  • AtomicLongArray
  • AtomicReferenceArray 

 

api和操作AtomicInteger类并不不同,仅仅是要指定index,数组的索引

字段更新器

  • AtomicReferenceFieldUpdater
  • AtomicIntegerFieldUpdater
  • AtomicLongFieldUpdater

利用字段更新器,可以针对对象的某个域进行原子操作,只能配合volatile修饰的字段使用,否则会报出异常

创建更新器

 原子累加器

 

可以看出,累加的操作中,AtomicLong比LongAdder慢一些。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值