Atomic Operations and multithreading Atomic Operations and multithreading multithreading multithreading

Atomic Operations and multithreading


Doing a = 28 (with a being an int) is an atomic operation. But doing a++ is not an atomic operation because it requires a read of the value of a, an incrementation, and a write to a of the result. As a result, if you used a++ to implement a thread-safe counter, you could have two threads reading the value concurrently (26 for example), then have both increment it and writing it concurrently, resulting in 27 as a result, instead of 28.

AtomicInteger solves this issue by providing atomic operations like the ones you listed. In my example, you would use incrementAndGet() for example, which would guarantee the end value is 28 and not 27.


Atomic means the operation completes without any possibility for something to happen between. eg. getAndDecrement(), on AtomicInteger, guarantees that the variable is returned AND decremented at the same time.

If it was not an atomic operation, the possibility would exist for the value to get decremented (eg. from 3 to 2), then modified by another thread (eg. changing it from 2 to 5), then returned as 5.


You need an AtomicInteger if you need to read a variable and write a result depending on the read value. For instance, i++ reads i (e.g. 3) and writes i+1 (e.g. 4). A thread may be interrupted meanwhile, and three other threads increment i too. Now that we get back, i actually has the value 6 but our thread still writes 4, based on what it read beforehand.

AtomicInteger.getAndIncrement ensures you're not interrupted and therefore always incrementing properly. Moreover, the result is always flushed into memory, whereas a non-volatile i might not be flushed to memory. In this case other threads might not even see the changes.