了解 AtomicBoolean 的常用方法 🧠🔒
AtomicBoolean
是 Java 中提供的一种线程安全的布尔类型操作类,属于 java.util.concurrent.atomic
包。它采用 CAS(Compare-And-Swap) 无锁机制,确保在多线程环境下对布尔值的原子操作。相比普通的 boolean
类型,AtomicBoolean
是专为并发编程设计的,适合检查标志位(如任务完成状态、控制共享资源访问等)。
以下是 AtomicBoolean
的常用方法和用途,它非常适合实现线程安全布尔逻辑。
AtomicBoolean
的常用方法 🌟
1. get()
- 获取当前值 🟢
public final boolean get();
描述:
- 返回当前的布尔值。
- 在多线程访问环境下,可以确保获取的是最新的值。
示例代码:
AtomicBoolean atomicBoolean = new AtomicBoolean(true);
System.out.println("当前状态: " + atomicBoolean.get()); // 输出: 当前状态: true
2. set(boolean newValue)
- 设置新值 🟡
public final void set(boolean newValue);
描述:
- 将布尔变量设置为指定的新值。
- 这是直接赋值,不涉及任何比较逻辑或安全检查。
示例代码:
AtomicBoolean atomicBoolean = new AtomicBoolean(false);
atomicBoolean.set(true); // 设置为 true
System.out.println("当前状态: " + atomicBoolean.get()); // 输出: 当前状态: true
3. getAndSet(boolean newValue)
- 获取当前值然后设置新值 🔄
public final boolean getAndSet(boolean newValue);
描述:
- 返回当前值,同时将变量的值更新为
newValue
。 - 在多线程环境中,确保该操作是原子性的。
示例代码:
AtomicBoolean atomicBoolean = new AtomicBoolean(false);
boolean oldValue = atomicBoolean.getAndSet(true); // 获取旧值并更新为 true
System.out.println("旧状态: " + oldValue); // 输出: 旧状态: false
System.out.println("新状态: " + atomicBoolean.get()); // 输出: 新状态: true
4. compareAndSet(boolean expected, boolean newValue)
- 比较并设置 🧪
public final boolean compareAndSet(boolean expected, boolean newValue);
描述:
- 如果当前值与预期值
expected
相等,则更新为newValue
,返回true
;否则不更新,返回false
。 - CAS 操作的核心方法,适合解决多线程环境下布尔值的竞争问题。
示例代码:
AtomicBoolean atomicBoolean = new AtomicBoolean(false);
boolean success = atomicBoolean.compareAndSet(false, true); // 预期值是 false,更新为 true
System.out.println("更新成功了吗?" + success); // 输出: 更新成功了吗?true
System.out.println("新状态: " + atomicBoolean.get()); // 输出: 新状态: true
5. weakCompareAndSet(boolean expected, boolean newValue)
- 弱比较并设置 🔍
public final boolean weakCompareAndSet(boolean expected, boolean newValue);
描述:
- 和
compareAndSet
很像,但不保证所有条件下操作都成功。通常用于性能优化,因为它可能在某些硬件环境下效率更高。 - 适用于一些不要求严格 CAS 控制的场景。
示例代码:
AtomicBoolean atomicBoolean = new AtomicBoolean(false);
boolean success = atomicBoolean.weakCompareAndSet(false, true); // 尝试更新
System.out.println("弱比较更新成功?" + success); // 输出: 弱比较更新成功?true 或 false
System.out.println("新状态: " + atomicBoolean.get()); // 输出可能会是 true 或 false,取决于硬件实现
6. lazySet(boolean newValue)
- 延迟设置 🕐
public final void lazySet(boolean newValue);
描述:
- 将变量更新为新值,但更新可能是 “延迟” 的,不会立即对其他线程可见。
- 目的是优化性能,避免多线程同时写操作时的开销。
示例代码:
AtomicBoolean atomicBoolean = new AtomicBoolean(false);
atomicBoolean.lazySet(true); // 延迟设置为 true
System.out.println("当前状态: " + atomicBoolean.get()); // 输出: 当前状态: true(多线程情况下可能稍后更新)
适用场景 💼
AtomicBoolean 的线程安全特性使它非常适合以下场景:
场景 1: 控制资源访问 🛡️
例如在多线程情况下控制某段代码的执行:
AtomicBoolean lock = new AtomicBoolean(false);
public void accessResource() {
if (lock.compareAndSet(false, true)) {
try {
System.out.println(Thread.currentThread().getName() + " 正在访问资源...");
// 模拟资源访问
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.set(false); // 释放锁
}
} else {
System.out.println(Thread.currentThread().getName() + " 无法访问资源,资源已被占用");
}
}
运行示例:
AtomicBoolean lock = new AtomicBoolean(false);
Runnable task = () -> accessResource();
Thread t1 = new Thread(task);
Thread t2 = new Thread(task);
t1.start();
t2.start();
场景 2: 中断控制 🔌
用于线程间布尔标志的安全传递,确保能准确触发操作:
AtomicBoolean stopFlag = new AtomicBoolean(false);
public void doWork() {
while (!stopFlag.get()) {
System.out.println(Thread.currentThread().getName() + " 正在工作...");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
public void stopWork() {
stopFlag.set(true);
System.out.println("工作已停止!");
}
运行示例:
AtomicBoolean stopFlag = new AtomicBoolean(false);
Thread worker = new Thread(() -> doWork());
worker.start();
// 模拟一段处理后停止工作
Thread.sleep(500);
stopWork();
场景 3: 状态同步 🔄
例如协作线程之间共享完成状态:
AtomicBoolean isCompleted = new AtomicBoolean(false);
class Task extends Thread {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " 正在执行任务...");
try {
Thread.sleep(1000); // 模拟任务处理
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
isCompleted.set(true);
System.out.println(Thread.currentThread().getName() + " 完成任务");
}
}
运行示例:
AtomicBoolean isCompleted = new AtomicBoolean(false);
Thread t1 = new Task();
t1.start();
while (!isCompleted.get()) {
System.out.println("等待任务完成...");
Thread.sleep(200); // 每 200ms 检查一次状态
}
System.out.println("任务已完成!");
总结 🧠
AtomicBoolean
是处理多线程环境下布尔值的利器。它提供了以下功能:
- 安全地读取和更新布尔标志位。
- 高效的 CAS 机制,适用于控制资源访问、工作中断等场景。
- 延迟和弱比较等优化方法,提升性能。