简体   繁体   English

是否有必要使“AtomicBoolean”也成为“volatile”?

[英]Is it necessary to make `AtomicBoolean` also `volatile`?

My understanding: Declaring a variable volatile guarantees the visibility for other threads about writes to that variable.我的理解:声明一个变量volatile可以保证其他线程对该变量的写入可见性 Essentially, every write to volatile variable happens-before subsequent reads .本质上,对 volatile 变量的每次write发生在后续reads之前。

I understand the atomicity of AtomicBoolean.compareAndSet() and how it provides the atomicity of read+write operation that volatile doesn't.我了解AtomicBoolean.compareAndSet()的原子性以及它如何提供volatile所没有的read+write操作的原子性。 But I don't see any doc providing visibility guarantee by AtomicBoolean like the following:但我没有看到任何文档提供AtomicBoolean可见性保证,如下所示:

  1. Every successful write by AtomicBoolean.compareAndSet() will eventually be visible to subsequent AtomicBoolean.get() and AtomicBoolean.compareAndSet() by other threads. AtomicBoolean.compareAndSet()的每次成功write最终都会被其他线程后续AtomicBoolean.get()AtomicBoolean.compareAndSet()看到。

But, I keep seeing code labelled as thread-safe which are like this,但是,我一直看到标记为thread-safe的代码是这样的,

// default false so that first-thread that execute() can enter the logic block
private static final  AtomicBoolean executing = new AtomicBoolean(false);


public void execute() {
    if (executing.compareAndSet(false, true)) {  // check if the executing is previously false and if so update it to true
        try {
            // thead-safe code, i.e only one thread guaranteed to execute at any point of time time
        } finally {
            executing.set(false); // executing thread now re-sets the test value
        }
    }
}

Shouldn't the variable executing also declared volatile , like private static volatile AtomicBoolean executing = new AtomicBoolean(false);不应该executing的变量也声明为volatile ,例如private static volatile AtomicBoolean executing = new AtomicBoolean(false); ? ? So the visibility guarantee needed by AtomicBoolean is achieved?那么AtomicBoolean所需要的可见性保证就实现了吗?

Is it necessary to make AtomicBoolean also volatile ?是否有必要使AtomicBooleanvolatile

No.不。

In the example, executing is declared as static final , so it will be initialized once at class initialization time and safely published to any other code that needs it.在示例中, executing被声明为static final ,因此它将在 class 初始化时初始化一次,并安全地发布到需要它的任何其他代码。

This behavior is guaranteed because there is a happens-before between a classes initialization completing (normally) and any subsequent use of any static variable declared by the class.这种行为是有保证的,因为在类初始化完成(通常)和任何后续使用由 class 声明的任何 static 变量之间存在发生之前 The fact that the variable is also final excludes any subsequent assignments to the static that would negate the happens-before .变量也是final的事实排除了对 static 的任何后续分配,这些分配将否定发生之前

You would only need to declare executing as volatile if something could assign a new value to it after initialization.如果某些东西可以在初始化后为其分配新值,则只需要将executing声明为volatile That's not possible here without doing some nasty reflection.如果不进行一些令人讨厌的反思,这是不可能的。 (And the JLS states that if you do that kind of thing to change a final , the memory model guarantees do not apply.) (并且 JLS 声明,如果你做那种事情来改变final ,memory model 保证不适用。)


You would get a similar effect if executing was final but an instance field rather than a static field.如果executingfinal的但实例字段而不是static字段,您将获得类似的效果。 The reasoning is slightly different, but it is also explicitly mentioned in the JLS.推理略有不同,但在 JLS 中也明确提及。


Finally, the Java syntax does not allow you to combine volatile and final modifiers.最后,Java 语法不允许您组合volatilefinal修饰符。 That combination doesn't make sense.这种组合没有意义。

We cannot use the below code我们不能使用下面的代码

private static volatile final AtomicBoolean executing = new AtomicBoolean(false);

Usage of volatile and final together is invalid . volatile 和 final 一起使用是无效的 As stated by @RealSkeptic var which would never change (final) need not have volatile.正如@RealSkeptic 所说,永远不会改变(最终)的 var 不需要 volatile。 Volatile is used for those vars whose values gets changed in runtime by one or more thread. Volatile 用于那些值在运行时被一个或多个线程更改的变量。

//Happy learning //快乐学习

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM