java.util.corrurnent.atomic


Boolean/Integer/Long/Array

compareAndSet(boolean expect, boolean update)

这个方法主要两个作用       

  1. 比较AtomicBoolean和expect的值,如果一致,执行方法内的语句。其实就是一个if语句       

  2. 把AtomicBoolean的值设成update        

 比较最要的是这两件事是一气呵成的,这连个动作之间不会被打断,任何内部或者外部的语句都不可能在两个动作之间运行。为多线程的控制提供了解决的方案。


public final boolean getAndSet(boolean newValue)

以原子方式设置为给定值,并返回以前的值。

扫描二维码关注公众号,回复: 1096306 查看本文章


public booleanweakCompareAndSet(boolean expect,

                                 boolean update)

如果当前值 == 预期值,则以原子方式将该值设置为给定的更新值。

可能意外失败并且不提供排序保证,因此几乎只是 compareAndSet 的适当替代方法。

void lazySet(boolean newValue)

最终会设置成newValue,使用lazySet设置值后,可能导致其他线程在之后的一小段时间内还是可以读到旧的值。


AtomicIntegerFieldUpdater/AtomicLongFieldUpdater

基于反射的实用工具,可以对指定类的指定 volatile int 字段进行原子更新。此类用于原子数据结构,该结构中同一节点的几个字段都独立受原子更新控制。

public static <U>AtomicIntegerFieldUpdater<U>newUpdater(Class<U> tclass,

                                                         String fieldName)

使用给定字段为对象创建和返回一个更新器。需要 Class 参数来检查反射类型和一般类型是否匹配。


AtomicStampedReference/AtomicMarkableReference

cas的ABA问题就是 假设初始值为A,线程3和线程1都获取到了初始值A,然后线程1将A改为了B,线程2将B又改回了A,这时候线程3做修改时,是感知不到这个值从A改为了B又改回了A的过程:

AtomicStampedReference 本质是有一个int 值作为版本号,每次更改前先取到这个int值的版本号,等到修改的时候,比较当前版本号与当前线程持有的版本号是否一致,如果一致,则进行修改,并将版本号+1(当然加多少或减多少都是可以自己定义的),在zookeeper中保持数据的一致性也是用的这种方式;

AtomicMarkableReference则是将一个boolean值作是否有更改的标记,本质就是它的版本号只有两个,true和false,修改的时候在这两个版本号之间来回切换,这样做并不能解决ABA的问题,只是会降低ABA问题发生的几率而已;











猜你喜欢

转载自blog.csdn.net/wangshixu2015/article/details/78458780