++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慢一些。
449

被折叠的 条评论
为什么被折叠?



