AtomicBoolean类的使用
程序员文章站
2022-06-07 19:51:32
...
最近在学习jdk的基本类库,发现AtomicBoolean类可以保证操作的原子性,记录一下.
简介
AtomicBoolean类的注释说明了它的使用方式,适用于多线程下 boolean 变量的原子性更新场景,即对于它的更新操作每次只能有一个线程执行,另外它不能完全替代 boolean 变量的作用.
使用方式
它的使用方式很简单
1.定义 AtomicBoolean 变量
private static AtomicBoolean flag = new AtomicBoolean(false);
2.在 if 判断语句中调用 compareAndSet(boolean expect, boolean update) 方法
if(flag.compareAndSet(false, true)) {
System.out.println(Thread.currentThread().getName() + ": Initialize...");
}
说明:
- 代码中的 compareAndSet() 方法的有两个作用.
- 一个是判断当前 flag 的值是否是 false,如果是则执行 if 代码块中的语句,如果不是则跳过.
- 第二个作用是如果 flag 的值为 false, 则将 flag 的值更新为 true.
- 另外 compareAndSet() 方法的执行,包括 if 语句的代码块,它们的执行是原子性的,即每次只能有一个线程执行.
使用场景
AtomicBoolean类适用于执行初始化任务,即某些代码在系统启动后,只需要执行一次的,就可以使用它了.
代码示例
1.不使用 AtomicBoolean 类,执行初始化加载.
public class AtomicTestThread {
private static boolean flag = false;
public static void print() {
System.out.println(Thread.currentThread().getName());
if(!flag) {
try {
// 等待100ms的原因是让所有的线程都进到这个方法里面
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + ": Initialize...");
flag = true;
}
}
public static void main(String[] args) {
new Thread(AtomicTestThread::print).start();
new Thread(AtomicTestThread::print).start();
new Thread(AtomicTestThread::print).start();
}
}
执行结果:
Thread-0
Thread-2
Thread-1
Thread-0: Initialize...
Thread-1: Initialize...
Thread-2: Initialize...
2.使用 AtomicBoolean 类执行初始化加载.
import java.util.concurrent.atomic.AtomicBoolean;
public class AtomicTestThread {
private static AtomicBoolean flag = new AtomicBoolean(false);
public static void print() {
System.out.println(Thread.currentThread().getName());
if(flag.compareAndSet(false, true)) {
try {
// 等待100ms的原因是让所有的线程都进到这个方法里面
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + ": Initialize...");
}
}
public static void main(String[] args) {
new Thread(AtomicTestThread::print).start();
new Thread(AtomicTestThread::print).start();
new Thread(AtomicTestThread::print).start();
}
}
执行结果:
Thread-1
Thread-2
Thread-0
Thread-1: Initialize...
3.AtomicBoolean 类的替代方案,使用 synchronized 关键字给代码块加个锁.
public class AtomicTestThread {
private static boolean flag = false;
public static void print() {
System.out.println(Thread.currentThread().getName());
synchronized(AtomicTestThread.class) {
if(!flag) {
try {
// 等待100ms的原因是让所有的线程都进到这个方法里面
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + ": Initialize...");
flag = true;
}
}
}
public static void main(String[] args) {
new Thread(AtomicTestThread::print).start();
new Thread(AtomicTestThread::print).start();
new Thread(AtomicTestThread::print).start();
}
}
打印结果:
Thread-0
Thread-1
Thread-2
Thread-0: Initialize...
总结
- 对于只需要执行一次的代码块,可以用 AtomicBoolean 类的对象作为判断标志位,使用也很方便,只要调用一下 compareAndSet() 方法即可.
上一篇: 简单理解复合优先于继承