【Java源码计划】AtomicBoolean<rt.jar_java.util.concurrent.atomic.AtomicBoolean>

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());
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 除了充分利用计算机处理器的能力外,一个服务端同时对多个客户端提供服务则是另一个更具体的并发应用场景。衡量一个服务性...
    胡二囧阅读 1,460评论 0 12
  • Java 面试随着时间的改变而改变。在过去的日子里,当你知道 String 和 StringBuilder 的区别...
    Java小铺阅读 10,935评论 1 336
  • 在一个方法内部定义的变量都存储在栈中,当这个函数运行结束后,其对应的栈就会被回收,此时,在其方法体中定义的变量将不...
    Y了个J阅读 4,573评论 1 14
  • Java SE 基础: 封装、继承、多态 封装: 概念:就是把对象的属性和操作(或服务)结合为一个独立的整体,并尽...
    Jayden_Cao阅读 2,247评论 0 8
  • 所有知识点已整理成app app下载地址 J2EE 部分: 1.Switch能否用string做参数? 在 Jav...
    侯蛋蛋_阅读 2,710评论 1 4

友情链接更多精彩内容