Java源码

【Java源码计划】AtomicBoolean<rt.ja

2019-04-01  本文已影响1人  DeanChangDM

AtomicBoolean

这个类是Automic包下的类,用于提供对应类型的原子操作

源码解析

这个类提供了一个可以原子更新的Boolean值。有关原子变量属性的描述,请参照java.util.concurrent.atomic包规范。AtomicBoolean可以用于作为原子更新的标志,但是不能作为java.lang.Boolean的替代使用。

这个类自JDK1.5开始提供

这个类实现了java.io.Serializable接口,关于java.io.Serializable接口详见对应的介绍

这里value变量使用了volatile修饰,关于volatile修饰放到关键字对应的内容下,简单说一下,熟悉这个关键词底层实现的人知道,这个关键词最终是加了内存屏障。主要体现在三点
1.保证写volatile变量会强制把CPU写缓存区的数据刷新到内存
2.读volatile变量时,使缓存失效,强制从内存中读取最新的值
3.由于内存屏障的存在,volatile变量还能阻止重排序

    //序列化ID
    private static final long serialVersionUID = 4654671469794556979L;
    // 获取Unsafe实例用于进行Unsafe的相关操作,详见Unsafe介绍
    private static final Unsafe unsafe = Unsafe.getUnsafe();
    //用于存储通过Unsafe获取的元素偏移量
    private static final long valueOffset;
    //用于存储元素的变量(整形)
    private volatile int value;

    //静态化块用于初始化valueOffset
    static {
        try {
            valueOffset = unsafe.objectFieldOffset
                (AtomicBoolean.class.getDeclaredField("value"));
        } catch (Exception ex) { throw new Error(ex); }
    }

接下来是用于初始化的构造方法

    //利用给定的初始化元素(布尔型)初始化一个新的AtomicBoolean
    public AtomicBoolean(boolean initialValue) {
        value = initialValue ? 1 : 0;
    }
    //无参构造函数,即将value按照默认的0初始化,也即是说初始化为false
    public AtomicBoolean() {
    }

接下来是一个用于获取value的方法

    public final boolean get() {
        //返回value元素所代表的布尔值,除0以外都是true
        return value != 0;
    }

再往下是原子操作

关于compareAndSet和weakCompareAndSet补充一个专题配合Volatile关键字一起写一个

    //如果当前的value元素和expect所期望的数据相同,利用给定的update原子化(CAS操作)更新value
    //返回true标示更新成功,返回false标示期望值和实际值不相同
    public final boolean compareAndSet(boolean expect, boolean update) {
        int e = expect ? 1 : 0;
        int u = update ? 1 : 0;
        //this用于传递第一个参数,作为当前对象(对于CAS操作来说就是目标所在的对象),
        //然后是valueOffset是目标属性偏移量
        //e是CAS操作的期望值
        //u是更新值
        return unsafe.compareAndSwapInt(this, valueOffset, e, u);
    }
    
    
    //这个方法在1.8之前都是和上面的那个一毛一样滴,但是这个方法作为一个接口职责,
    //对上层调用不能保证调用的失败的时候是真正的失败,换句话说有可能是虚假的失败
    //但是一般来说这个方法所提供的效率要高于上一个
    //1.9中这个方法仍然是和上一个一样的,但是在jdk1.9中开始出现了一个@HotSpotIntrinsicCandidate注解
    //这个注解表达了虽然你看到的源码是一样的,但是不排除虚拟机对这个进行优化的可能性
    public boolean weakCompareAndSet(boolean expect, boolean update) {
        int e = expect ? 1 : 0;
        int u = update ? 1 : 0;
        return unsafe.compareAndSwapInt(this, valueOffset, e, u);
    }

设置value的方法

    //这个方法无条件的将元素设定为给定的值
    public final void set(boolean newValue) {
        value = newValue ? 1 : 0;
    }

这个方法只能保证最终会设置为给定的值,不能保证存储对其他线程的立即可见,也就是说这个更改是有延迟的。这个方法通常只有在底层字段是volatile修饰的时候才能生效。value是在Volatile修饰下的

    public final void lazySet(boolean newValue) {
        int v = newValue ? 1 : 0;
        unsafe.putOrderedInt(this, valueOffset, v);
    }

原子的更新元素,然后把之前的值返回回去


    public final boolean getAndSet(boolean newValue) {
        boolean prev;
        //自旋锁,每次CAS失败后都会重新读取
        do {
            prev = get();
        } while (!compareAndSet(prev, newValue));
        return prev;
    }

把元素按照String返回


    public String toString() {
        return Boolean.toString(get());
    }
上一篇下一篇

猜你喜欢

热点阅读