Why can't AtomicBoolean be a replacement for Boolean?

Brooks picture Brooks · Apr 29, 2016 · Viewed 7k times · Source

The Oracle JDK Javadoc for AtomicBoolean states:

https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/atomic/AtomicBoolean.html

A boolean value that may be updated atomically. See the java.util.concurrent.atomic package specification for description of the properties of atomic variables. An AtomicBoolean is used in applications such as atomically updated flags, and cannot be used as a replacement for a Boolean.

A colleague and I were trying to figure out a use-case where the AtomicBoolean can't be a substitute and the only thing we can think of is that there are methods the Boolean object has that the AtomicBoolean does not.

Is that the only reason or was there something else in mind when that was written?

Answer

Nathan Hughes picture Nathan Hughes · Apr 29, 2016

Boolean is an immutable value object. It was designed to be unchanging and made final in order to enforce that. java.lang.Boolean has been around since 1.0.

AtomicBoolean is mutable, and designed to get updated so that the updated value is visible across threads. AtomicBoolean was introduced with Java 5.

These are entirely different concepts, which is why AtomicBoolean wasn't designed to extend Boolean. You can't substitute a mutable object for an immutable one without wrecking the expected invariants of the code using it. Code expecting to receive an immutable value could get broken if the atomic version could be passed in in its place.

So here's a use case: if AtomicBoolean was introduced as something that was substitutable for Boolean, you could have a case where a class created before this change could reasonably expect that in some method that returns a Boolean it doesn't need to pass a defensive copy on account of Boolean being immutable. If the reference returned happens to get initialized from a source that changes to use AtomicBoolean instead of Boolean, then that field could now be modified by things calling the method returning Boolean, by casting it to AtomicBoolean.

The atomic classes are designed for working with concurrent updates (as an improvement on volatile), but the most efficient way to design concurrent code is to use immutable values. So be careful not to mistake AtomicBoolean for "the Boolean you use when writing multithreaded code".