美文网首页Java源码
【Java源码计划】AtomicBoolean<rt.ja

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

作者: DeanChangDM | 来源:发表于2019-04-01 15:31 被阅读1次

    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());
        }
    

    相关文章

      网友评论

        本文标题:【Java源码计划】AtomicBoolean<rt.ja

        本文链接:https://www.haomeiwen.com/subject/qlpvbqtx.html