理解AtomicBoolean

简介: 这里我们就从AtomicBoolean开始说吧,自己正好也复习一下。对于官方的说明是:可以用原子方式更新的 boolean 值。有关原子变量属性的描述,请参阅 java.util.concurrent.atomic包规范。

这里我们就从AtomicBoolean开始说吧,自己正好也复习一下。对于官方的说明是:

可以用原子方式更新的 boolean 值。有关原子变量属性的描述,请参阅 java.util.concurrent.atomic
包规范。AtomicBoolean 可用在应用程序中(如以原子方式更新的标志),但不能用于替换 Boolean。

换一句话说,Atomic就是原子性的意思,即能够保证在高并发的情况下只有一个线程能够访问这个属性值。(类似我们之前所说的volatile)

一般情况下,我们使用 AtomicBoolean 高效并发处理 “只初始化一次” 的功能要求:

private static AtomicBoolean initialized = new AtomicBoolean(false);
public void init()
{
   if( initialized.compareAndSet(false, true) )
   {
       // 这里放置初始化代码....
   }
}

如果没有AtomicBoolean,我们可以使用volatile做如下操作:

public static volatile initialized = false;
public void init()
{
    if( initialized == false ){
        initialized = true;
        // 这里初始化代码....
    }
}

既然如此神奇,那么我们看看AtomicBoolean的源码时如何实现的,查看源码如下:

public class AtomicBoolean implements java.io.Serializable {
    private static final long serialVersionUID = 4654671469794556979L;
    // setup to use Unsafe.compareAndSwapInt for updates
    private static final Unsafe unsafe = Unsafe.getUnsafe();
    private static final long valueOffset;

    static {
        try {
            valueOffset = unsafe.objectFieldOffset
                (AtomicBoolean.class.getDeclaredField("value"));
        } catch (Exception ex) { throw new Error(ex); }
    }

    private volatile int value;

    /**
     * Creates a new {@code AtomicBoolean} with the given initial value.
     *
     * @param initialValue the initial value
     */
    public AtomicBoolean(boolean initialValue) {
        value = initialValue ? 1 : 0;
    }

    /**
     * Creates a new {@code AtomicBoolean} with initial value {@code false}.
     */
    public AtomicBoolean() {
    }

    /**
     * Returns the current value.
     *
     * @return the current value
     */
    public final boolean get() {
        return value != 0;
    }

    /**
     * Atomically sets the value to the given updated value
     * if the current value {@code ==} the expected value.
     *
     * @param expect the expected value
     * @param update the new value
     * @return {@code true} if successful. False return indicates that
     * the actual value was not equal to the expected value.
     */
    public final boolean compareAndSet(boolean expect, boolean update) {
        int e = expect ? 1 : 0;
        int u = update ? 1 : 0;
        return unsafe.compareAndSwapInt(this, valueOffset, e, u);
    }

    /**
     * Atomically sets the value to the given updated value
     * if the current value {@code ==} the expected value.
     *
     * <p><a href="package-summary.html#weakCompareAndSet">May fail
     * spuriously and does not provide ordering guarantees</a>, so is
     * only rarely an appropriate alternative to {@code compareAndSet}.
     *
     * @param expect the expected value
     * @param update the new value
     * @return {@code true} if successful
     */
    public boolean weakCompareAndSet(boolean expect, boolean update) {
        int e = expect ? 1 : 0;
        int u = update ? 1 : 0;
        return unsafe.compareAndSwapInt(this, valueOffset, e, u);
    }

    /**
     * Unconditionally sets to the given value.
     *
     * @param newValue the new value
     */
    public final void set(boolean newValue) {
        value = newValue ? 1 : 0;
    }

    /**
     * Eventually sets to the given value.
     *
     * @param newValue the new value
     * @since 1.6
     */
    public final void lazySet(boolean newValue) {
        int v = newValue ? 1 : 0;
        unsafe.putOrderedInt(this, valueOffset, v);
    }

    /**
     * Atomically sets to the given value and returns the previous value.
     *
     * @param newValue the new value
     * @return the previous value
     */
    public final boolean getAndSet(boolean newValue) {
        boolean prev;
        do {
            prev = get();
        } while (!compareAndSet(prev, newValue));
        return prev;
    }

    /**
     * Returns the String representation of the current value.
     * @return the String representation of the current value
     */
    public String toString() {
        return Boolean.toString(get());
    }

}

你猜的没错,AtomicBoolean就是使用了Volatile属性来完成的。

Java6以后出现的很多的原子行的类,除了上述我们所说的AtomicBoolean以外,AtomicBoolean家族还是比较强大的,后面我们有时间在一一介绍。包括:

基本类:
AtomicInteger、AtomicLong、AtomicBoolean;
引用类型:
AtomicReference、AtomicReference的ABA实例、AtomicStampedRerence、AtomicMarkableReference;
数组类型:
AtomicIntegerArray、AtomicLongArray、AtomicReferenceArray
属性原子修改器(Updater):
AtomicIntegerFieldUpdater、AtomicLongFieldUpdater、AtomicReferenceFieldUpdater

目录
相关文章
|
Android开发
Android--文件或目录拷贝、复制、粘贴
版权声明:本文为博主原创文章,转载请标明出处。 https://blog.csdn.net/chaoyu168/article/details/53762886 需要给 AndroidManifest.
2454 0
|
10月前
|
容器
Flutter灵活布局要掌握的两个控件Expanded和Flexible
Flutter灵活布局要掌握的两个控件Expanded和Flexible
|
设计模式 搜索推荐 算法
JDK中的排序:Arrays.sort的源码实现
JDK中的排序:Arrays.sort的源码实现
422 0
JDK中的排序:Arrays.sort的源码实现
|
安全 Java
java并发原子类AtomicBoolean解析
如果看过我之前的文章都知道这几天一直在更新java多线程这块的知识点,因为这块的知识点确实是比较多而且也别繁杂,因此对于java多线程基础知识点也会在两个多月的时间全部写完,这篇文章主要是针对java并发包下的一个原子类AtomicBoolean的讲解。
205 0
java并发原子类AtomicBoolean解析
|
编解码
【经典蓝牙】蓝牙AVRCP协议分析
蓝牙AVRCP协议是蓝牙设备之间音视频的控制协议。定义了音频/视频的控制、浏览、查询、通知等一系列的命令集。常用来蓝牙耳机对手机的音乐进行控制,以及获取手机的音乐信息等场景。AVRCP协议有两个角色,分别是controller(CT)和 target(TG)。CT: 发送控制命令到对端,控制对端媒体播放器的设备,例如蓝牙耳机,蓝牙遥控器等。TG:接收对端的控制命令,并执行操作,进行回复的设备,例如手机,电脑等。
1980 0
【经典蓝牙】蓝牙AVRCP协议分析
|
Ubuntu
Ubuntu12.04(32bit)下安装bison和flex
Ubuntu12.04(32bit)下安装bison和flex
568 0
|
XML Android开发 数据格式
Android 10.0 Settings 加载流程(一)
Android 10.0 Settings 加载流程(一)
|
SQL 存储 Java
Statement和PreparedStatement的区别; 什么是SQL注入,怎么防止SQL注入? (转)
问题一:Statement和PreparedStatement的区别   先来说说,什么是java中的Statement:Statement是java执行数据库操作的一个重要方法,用于在已经建立数据库连接的基础上,向数据库发送要执行的SQL语句。
4397 0
|
Android开发
【Android 高性能音频】AAudio 缓冲区控制 ( XRun | 欠载 UnderRun | 超限 OverRun | 获取缓冲区大小 | 设置缓冲区大小 )
【Android 高性能音频】AAudio 缓冲区控制 ( XRun | 欠载 UnderRun | 超限 OverRun | 获取缓冲区大小 | 设置缓冲区大小 )
660 0
|
Java Android开发 C++
preload-classes的前世今生(1)
Android的preload-classes是一种通过预加载来加快应用启动速度的好办法,这篇文章来讲如何针对某特定手机去实现自己预加载列表。
7985 0