AtomicBoolean,设置标志一次,有必要吗?静态布尔值可以吗?

AtomicBoolean, set flag once, necessary? Might a static boolean be ok?

我正在设置一个标志,该标志由任何要设置它的线程设置一次。所有其他线程都会在不同的时间,经常重复读取这个标志。

现在我正在使用 AtomicBoolean,它工作正常,但我知道如果经常查询它,它可能比普通布尔值慢得多,(不确定这是不是真的)。

将其更改为静态布尔值是否线程安全?任何人都可以将标志设置为真,事实上,所有人都可以多次设置标志。

我担心的是那些阅读旗帜的人能多快发现它?会不会是对的?或者他们可能做错了?

此外,使用经常查询的 AtomicBoolean 对性能的影响有多大?

此外,我是否应该考虑在 AtomicBoolean 上使用 volatile 布尔值,因为我几乎只设置一次并读取它,并且可以自动执行设置操作(复制 AtomicBoolean 中的代码以获取 getAndSet())

如果一个线程设置值而其他线程读取它,则 volatile 工作正常。

如果很多线程可能将它设置为 true 而你不关心哪个线程实际执行它,然后其他线程只读取它,volatile 也可以正常工作。

如果很多线程可以设置它true/false,那么原子的,或者同步的,或者一些锁结构是唯一的方法。

是的,原子、同步等存在性能问题。但安全通常比这更重要。

当大多数线程只读取变量并且只有其中一个线程会更改值时,您无需担心性能问题。 AtomicBoolean 使用一种称为 CAS 的机制,现在大多数现代处理器都支持这种机制,并且是一种低级操作。由于使用 CAS,在读取值时几乎没有任何缺点(这与使用标准锁不同)。对于您描述的场景 volatile static boolean 就足够了 - volatile 阻止 jvm 在读取变量时进行优化,例如重用寄存器中保存的值而不是检查内存中的值,因此每当一个线程更改变量的值时,其他线程就会看到改变。在您的情况下,两种解决方案即使不相同,也会提供相似的性能结果。 在有很多写操作的场景下,Volatile 会比 AtomicBoolean 更快,但老实说,我无法想象你有很多写操作而没有人有兴趣阅读的场景。

如果变量仅由任何线程设置一次并且以后永远不会更改,您可以使用条件同步块通过消除不必要的同步调用来获得一些性能。

但我认为这不值得去做。只需使用 AtomicBoolean 或 volatile 变量。

public class Sandbox1 {
    private boolean status;

    public void setStatus(boolean status) {
        if (!this.status) {
            synchronized (this) {
                this.status = status;
            }
        }
    }

    public boolean isStatus() {
        if (!this.status) {
            synchronized(this) {
                return this.status;
            }
        }
        return this.status;
    }
}