What does AtomicBoolean do that a volatile boolean cannot achieve?
相关问题
- Delete Messages from a Topic in Apache Kafka
- Jackson Deserialization not calling deserialize on
- How to maintain order of key-value in DataFrame sa
- StackExchange API - Deserialize Date in JSON Respo
- Difference between Types.INTEGER and Types.NULL in
If you have only one thread modifying your boolean, you can use a volatile boolean (usually you do this to define a
stop
variable checked in the thread's main loop).However, if you have multiple threads modifying the boolean, you should use an
AtomicBoolean
. Else, the following code is not safe:This operation is done in two steps:
If an other thread modify the value between
#1
and2#
, you might got a wrong result.AtomicBoolean
methods avoid this problem by doing steps#1
and#2
atomically.volatile
keyword guarantees happens-before relationship among threads sharing that variable. It doesn't guarantee you that 2 or more threads won't interrupt each other while accessing that boolean variable.The Atomic* classes wrap a volatile primitive of the same type. From the source:
So if all you are doing is getting and setting a Atomic* then you might as well just have a volatile field instead.
What the Atomic* classes give you however, are methods that provide more advanced functionality such as
incrementAndGet()
,compareAndSet()
, and others that implement multiple operations (get/increment/set, test/set) without locking. That's why the Atomic* classes are so powerful.For example, if multiple threads are using the following code using
++
, there will be race conditions because++
is actually: get, increment, and set.However, the following code will work in a multi-threaded environment safely:
It's also important to note that wrapping your volatile field using Atomic* class is a good way to encapsulate the critical shared resource from an object standpoint. This means that developers can't just deal with the field assuming it is not shared possibly injecting problems with a field++; or other code that introducing race conditions.
AtomicBoolean
has methods that perform their compound operations atomically and without having to use asynchronized
block. On the other hand,volatile boolean
can only perform compound operations if done so within asynchronized
block.The memory effects of reading/writing to
volatile boolean
are identical to theget
andset
methods ofAtomicBoolean
respectively.For example the
compareAndSet
method will atomically perform the following (without asynchronized
block):Hence, the
compareAndSet
method will let you write code that is guaranteed to execute only once, even when called from multiple threads. For example:Is guaranteed to only notify the listener once (assuming no other thread sets the
AtomicBoolean
back tofalse
again after it being set totrue
).