Volatile Boolean VS Atomicboolean

Volatile boolean vs AtomicBoolean

They are just totally different. Consider this example of a volatile integer:

volatile int i = 0;
void incIBy5() {
i += 5;
}

If two threads call the function concurrently, i might be 5 afterwards, since the compiled code will be somewhat similar to this (except you cannot synchronize on int):

void incIBy5() {
int temp;
synchronized(i) { temp = i }
synchronized(i) { i = temp + 5 }
}

If a variable is volatile, every atomic access to it is synchronized, but it is not always obvious what actually qualifies as an atomic access. With an Atomic* object, it is guaranteed that every method is "atomic".

Thus, if you use an AtomicInteger and getAndAdd(int delta), you can be sure that the result will be 10. In the same way, if two threads both negate a boolean variable concurrently, with an AtomicBoolean you can be sure it has the original value afterwards, with a volatile boolean, you can't.

So whenever you have more than one thread modifying a field, you need to make it atomic or use explicit synchronization.

The purpose of volatile is a different one. Consider this example

volatile boolean stop = false;
void loop() {
while (!stop) { ... }
}
void stop() { stop = true; }

If you have a thread running loop() and another thread calling stop(), you might run into an infinite loop if you omit volatile, since the first thread might cache the value of stop. Here, the volatile serves as a hint to the compiler to be a bit more careful with optimizations.

When is it preferable to use volatile boolean in Java rather than AtomicBoolean?

Essentially all AtomicBoolean is a volatile boolean in an object.

There will be a small overhead per object. Probably insignificant, but possibly more memory to get into cache.

If you need to use AtomicBooleanFieldUpdater then there is quite a lot of performance overhead.It can be okay if you aren't going to do it often (as attach in NIO).

AtomicBoolean vs volatile

using a AtomicBoolean all read and write actions are atomic (as the name includes). with a volatile boolean you still have to deal with race conditions, when two threads accessing the variable at the same time.

volatile vs Atomic boolean

AtomicBoolean and volatile have the exact same semantics in your usage (single writer), so either will work. The case for AtomicBoolean (or any Atomic class) is when you have to deal with multiple potential writers.

When do I need to use AtomicBoolean in Java?

When multiple threads need to check and change the boolean. For example:

if (!initialized) {
initialize();
initialized = true;
}

This is not thread-safe. You can fix it by using AtomicBoolean:

if (atomicInitialized.compareAndSet(false, true)) {
initialize();
}

Is it necessary to make `AtomicBoolean` also `volatile`?

Is it necessary to make AtomicBoolean also volatile?

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.

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. The fact that the variable is also final excludes any subsequent assignments to the static that would negate the happens-before.

You would only need to declare executing as volatile if something could assign a new value to it after initialization. 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.)


You would get a similar effect if executing was final but an instance field rather than a static field. The reasoning is slightly different, but it is also explicitly mentioned in the JLS.


Finally, the Java syntax does not allow you to combine volatile and final modifiers. That combination doesn't make sense.

Can AtomicBoolean replace volatile boolean?

There are two important differences between your two examples.

First, the obvious: The doInit() method in your first example only sets isInitialized=true after initializing the singleton. But, in your second example, it sets the AtomicBoolean instance to true before it initializes the singleton. That could be a problem if a second thread obtains a reference to the singleton after the flag has been set, but before the initialization has completed.

The second problem is less obvious: There is no synchronization after the flag is set in your second example. Nothing establishes a happens before relationship between the initialization code and anything that happens in some other thread. In your first example, the initialization happens before isInitialized=true, and isInitialized=true happens before any other thread tests if(!isInitialized)...

In your second example, if two threads concurrently call doInit(), The Atomic operation ensures that only one of them can enter the initialization code. But even if the winner, by pure chance, actually completes the initialization code before* the other thread starts to use the singleton object, there still is no formal happens before relationship between the first thread doing the initialization and the second thread accessing the singleton.


* "before" in real time (a.k.a., wall clock time). If some event A actually happens before event B in real time, but there is no formal happens before relationship between the two events, then it is possible for some other thread to see the effects of those two events as if they happened in a different order.



Related Topics



Leave a reply



Submit