AtomicBoolean详解(5大使用方法场景及原理)

AtomicBoolean详解(5大使用方法场景及原理)-mikechen

AtomicBoolean简介

AtomicBoolean类位于java.util.concurrent.atomic包下的原子变量,AtomicBoolean是Java中的一个原子类,用于表示一个布尔类型的值。

 

AtomicBoolean作用

AtomicBoolean主要的作用就是:提供对布尔类型变量的原子操作,这样可以避免并发访问时的竞态条件和数据不一致的问题。

 

AtomicBoolean使用场景

如果需要对某个boolean类型的变量进行原子操作,可以考虑使用AtomicBoolean,它主要有以下应用场景:

1.控制某个操作的执行

AtomicBoolean可以用来控制某个操作的执行,比如在一个多线程环境下,只允许一个线程执行某个操作。

可以将AtomicBoolean对象初始化为false,然后在需要执行该操作的线程中使用compareAndSet()方法将其设置为true。

2.作为一种开关

AtomicBoolean还可以作为一种开关,用于控制某个功能的开启和关闭。

比如:在一个多线程环境下,可以使用AtomicBoolean对象表示某个功能的开启状态,如果AtomicBoolean对象的值为true,则表示该功能已经开启,否则表示该功能已经关闭。

3.替代volatile boolean

AtomicBoolean可以替代volatile boolean,因为它可以提供与volatile相同的可见性和线程安全性,同时还提供了compareAndSet()方法,可以实现原子操作。

 

AtomicBoolean方法使用

1.AtomicBoolean构造函数

AtomicBoolean它有两个构造方法,如下所示:

public AtomicBoolean(boolean initialValue) {
    value = initialValue ? 1 : 0;
}

public AtomicBoolean() {
}

第二个构造方法AtomicBoolean​(boolean initialValue),可以指定初始值。

 

2.AtomicBoolean获取值

采用get()方法,如下所示:

AtomicBoolean atomicBoolean = new AtomicBoolean();
boolean value = atomicBoolean.get();
System.out.println(value);

get():返回AtomicBoolean对象的当前值。

 

3.AtomicBoolean设置值

可以使用 set() 方法对值进行重新设置,如下所示:

atomicBoolean.set(true);

set(boolean newValue):将AtomicBoolean对象的值设置为newValue。

 

4.compareAndSet进行原子更新

可以使用compareAndSet进行原子更新,如下所示:

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

如果AtomicBoolean对象的当前值等于expect,则将其设置为update,并返回true,否则返回false。

 

5.核心操作 getAndSet

以原子方式设置为给定值并返回前一个值,底层实现如下:

public final boolean getAndSet(boolean newValue) {
    boolean prev;
    do {
        prev = get();
    } while (!compareAndSet(prev, newValue));
    return prev;
}

getAndSet(boolean newValue):将AtomicBoolean对象的值设置为newValue,并返回原来的值。

 

AtomicBoolean实现原理

AtomicBoolean的实现原理是基于CAS(Compare and Swap)算法。

CAS是一种无锁算法,它通过比较对象的当前值和预期值是否相等来实现原子操作。

如下图所示:

AtomicBoolean详解(5大使用方法场景及原理)-mikechen

如上图显示,两个线程:线程1和线程2同时修改值,如果通过CAS来实现,具体流程如下:

  1. 在内存地址V当中,存储着值为7的变量
  2. 线程1想要把变量的值增加1,对线程1来说,旧的预期值A=7,要修改的新值B=8
  3. 线程2抢先一步,把内存值V修改:8
  4. 线程1开始提交更新,首先对比了预期值A=7和实际值V的比较8(Compare),发现A不等于V的实际值,提交失败

在多线程环境下,多个线程可以同时尝试执行CAS操作,但只有一个线程能够成功执行操作,其他线程则需要重试。

 

陈睿mikechen

10年+大厂架构经验,资深技术专家,就职于阿里巴巴、淘宝、百度等一线互联网大厂。

关注「mikechen」公众号,获取更多技术干货!

后台回复面试即可获取《史上最全阿里Java面试题总结》,后台回复架构,即可获取《阿里架构师进阶专题全部合集

评论交流
    说说你的看法