I have an atomic boolean property in Java
private AtomicBoolean endOfInputDataSet;
What are the proper getter and setter of this property and what are the consequences of each choice? I can return the AtomicBoolean directly
public AtomicBoolean getEndOfInputDataSet() {
return this.endOfInputDataSet;
}
public void setEndOfInputDataSet(AtomicBoolean endOfInputDataSet) {
this.endOfInputDataSet = endOfInputDataSet;
}
or I can return the unwrapped boolean:
public boolean getEndOfInputDataSet() {
return this.endOfInputDataSet.get();
}
public void setEndOfInputDataSet(boolean endOfInputDataSet) {
this.endOfInputDataSet.set(endOfInputDataSet);
}
I think the latter solution is just simpler for using by the client and cleaner, but why is it not default when IntelliJ generates the getter and setter?
tl;dr
Share the
Atomic…object container, not its payload value.Do share access to
AtomicBooleanobjectFor multiple threads to coordinate around the value contained in the payload of an
Atomic…object, the threads must have simultaneous direct access to theAtomic…object itself.Do not share copies of the value within the
AtomicBooleanEmitting copies of the value to the various threads breaks the atomic nature of the interaction intended by use of
Atomic…class. Making copies of the payload’s value is not thread-safe, with the threads now unable to coordinate around a single value.Details
Make that
finalto prevent anotherAtomicBooleanobject from being assigned to replace the original.And you might as well instantiate in the declaration.
The Atomic… objects are containers that carry a payload while providing thread-safe access to that payload.
This line returns a reference to that container. The calling programmer may then get or set the content of that payload.
This line ruins your scenario. You enable the calling programmer to replace your container.
This line returns a copy of the content of your container.
Be aware that this line‘s method is returning “old news”. There is a beat of time between the end of the
get()call and the moment when the calling programmer actually receives the value. During that beat, another thread may have executed aseton the atomic container, changing the content of the container. You have undone the “Atomic” inAtomicBoolean. This code is not thread-safe.And there are further beats of time between (a) the calling method receiving our returned copy of the payload’s value and (b) the calling method making use of that value. During these additional beats the calling actual payload in the
AtomicBooleanobject could be changing.This line is non-atomic and thread-unsafe in the same way as the line above it.
Because such code is not thread-safe.
When trying to coordinate multiple threads around a single value, those threads must all be dealing simultaneously with the very same value, the value carried as the payload within the atomic wrapper. To accomplish that, all the threads must be dealing with the atomic wrapper container directly.
So, you don’t really need getter/setter accessor methods here. Just make the atomic object
finaland directly accessible (publicetc.).Think of a bunch of kids in a classroom trying to coordinate their activity around a message in an envelope. If you let various kids copy that message while other kids are changing the message, you have chaos. To coordinate the kids’ activity, they must be simultaneously viewing the one and only message carried in that envelope.