I've read in Oracle docs that:
- Reads and writes are atomic for reference variables and for most
primitive variables (all types except long and double).
(I guess this feature has been added in some new JDK release because I used to think that reads/writes of ALL primitive variables are NOT atomic)
Does it mean that AtomicInteger
is deprecated and shouldn't be used in new projects?
The Java AtomicInteger class is used in applications such as atomically incremented counters. This class provides operations on underlying int value that can be read and written atomically. This class contains set and get methods that work like reads and writes on volatile variables. This method atomically adds the given value to the current value.
3. Conclusion. As discussed above, the primary use of AtomicInteger is when we are in multi-threaded context and we need to perform atomic operations on an int value without using synchronized keyword. Using the AtomicInteger is equally faster and more readable than performing the same using synchronization.
At runtime, those APIs make use of specialized CPU instructions which are able to perform both a read and a write as a single unit of work. A single read or write to a word-aligned, word-sized (or smaller) value is atomic, e.g.:
An atomic operation is, by definition, a single operation that either succeeds completely or fails completely. Since number++ performs multiple independent operations, it is not atomic. There are, however, APIs to increment a value atomically as a single operation.
While a single store to or a single load from an ordinary int
is atomic in Java, you cannot atomically, say, increment it. Doing so would require you to first load the value, then compute the new value depending on it and then store the new value back. But between the two accesses, another thread might have modified the value. AtomicInteger
provides operations like getAndIncrement
that can be used for this purpose without having to use a lock.
Deprecated? Not at all. While individual reads and writes of primitive variables are atomic, AtomicInteger
(and the other atomic classes in java.util.concurrent.atomic
) provides more complex operations that are also atomic. These include things like addAndGet(int)
, which are not at all atomic for primitive int
variables. Thus,
int i = 3;
AtomicInteger j = new AtomicInteger(3);
i += 5; // NOT thread-safe -- might not set i to 8
int n = j.addAndGet(5); // thread-safe -- always sets n to 8
(Both of the comments above are under the assumption that i
and j
are not changed by the time the statement in question starts executing, but might be changed by another thread after execution starts but before it is finished.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With