📜  Java并发-AtomicBoolean类(1)

📅  最后修改于: 2023-12-03 14:43:00.867000             🧑  作者: Mango

Java并发-AtomicBoolean类

Java提供了一系列的原子类(Atomic Class),用于在并发场景中执行线程安全的操作,其中之一就是AtomicBoolean类。

AtomicBoolean类的概述

AtomicBoolean类是Java中的原子布尔类,它提供了原子性操作,能够在多线程环境下进行操作。可以看作一种线程安全的布尔变量类型,具有原子性、可见性和有序性。

public class AtomicBoolean extends Object implements Serializable {

    /**
     * Creates a new AtomicBoolean with the given initial value.
     *
     * @param initialValue the initial value
     */
    public AtomicBoolean(boolean initialValue) {
        ...
    }

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

    /**
     * Sets to the given value.
     *
     * @param newValue the new value
     */
    public final void set(boolean newValue) {
        ...
    }

    /**
     * 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) {
        ...
    }

    /**
     * Atomically sets to the given value and returns the old value.
     *
     * @param newValue the new value
     * @return the previous value
     */
    public final boolean getAndSet(boolean newValue) {
        ...
    }

    ...
}
使用AtomicBoolean类
原子性操作

AtomicBoolean类提供了多个原子性操作方法,如get()set()compareAndSet()getAndSet()等,这些方法都是线程安全的,避免了多线程情况下的数据竞争和锁竞争,确保数据的正确性和一致性。

AtomicBoolean atomicBoolean = new AtomicBoolean(false);
boolean result = atomicBoolean.compareAndSet(false, true);
System.out.println(result); // true
System.out.println(atomicBoolean.get()); // true

上述代码中,我们创建了一个初始值为false的AtomicBoolean对象,然后执行了compareAndSet(false, true)方法,该方法会尝试将当前值和期望值进行比较,如果相同,则将当前值设置为给定的更新值,返回true,否则返回false。在这个例子中,由于当前值为false,期望值为false,所以更新成功,返回true。接着我们通过get()方法获取当前值并输出。

可见性操作

AtomicBoolean类提供了可见性操作,即一次修改后,即对其他线程可见。Java中的volatile关键字只能保证可见性,不能保证原子性,而AtomicBoolean类既能保证可见性,又能保证原子性。

public class Task implements Runnable {

    private AtomicBoolean stop;

    public Task(AtomicBoolean stop) {
        this.stop = stop;
    }

    @Override
    public void run() {
        while (!stop.get()) {
            // do something
        }
        System.out.println("Thread stopped.");
    }
}

public class Main {

    public static void main(String[] args) {
        AtomicBoolean atomicBoolean = new AtomicBoolean(false);
        Task task = new Task(atomicBoolean);
        new Thread(task).start();
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        atomicBoolean.set(true);
        System.out.println("Main thread set stop flag.");
    }
}

上述代码中,我们首先创建了一个AtomicBoolean对象,将其赋值为false,然后创建了一个Task对象,将AtomicBoolean对象传入,然后再新建一个线程执行该任务。该任务会循环执行某个操作,直到AtomicBoolean对象的值变为true,然后结束线程。在主线程中,我们先休眠5秒钟后,再将AtomicBoolean对象的值设置为true,以触发任务的结束。运行代码,可以看到程序输出了以下结果:

Main thread set stop flag.
Thread stopped.

这说明任务能够在主线程将AtomicBoolean对象的值设置为true后,及时地将循环停止。

适用场景

AtomicBoolean类适用于需要在多线程环境下对布尔变量类型进行原子性修改操作的场景。比如:

  • 控制某个线程的执行流程
  • 实现单例模式中的double-check locking
  • 实现简单的锁
总结

AtomicBoolean类是Java中的原子布尔类,能够在多线程环境下实现线程安全的操作,具有原子性、可见性和有序性,适用于需要对布尔变量类型进行原子性修改操作的场景。AtomicBoolean的原子性操作方法包括get()set()compareAndSet()getAndSet()等,可见性操作可以替代Java中的volatile关键字。