I have a need for a counter of type long
with the following requirements/facts:
Based upon these requirements, how would you choose to implement your counter? As a simple long
, as a volatile long
or using an AtomicLong
? Why?
At the moment I have a volatile long
but was wondering whether another approach would be better. I am also incrementing my long by doing ++counter
as opposed to counter++
. Is this really any more efficient (as I have been led to believe elsewhere) because there is no assignment being done?
An AtomicLong is used in applications such as atomically incremented sequence numbers, and cannot be used as a replacement for a Long . However, this class does extend Number to allow uniform access by tools and utilities that deal with numerically-based classes.
AtomicLong class provides operations on underlying long value that can be read and written atomically, and also contains advanced atomic operations. AtomicLong supports atomic operations on underlying long variable. It have get and set methods that work like reads and writes on volatile variables.
getAndIncrement() is an inbuilt method in java that increases the given value by one and returns the value before updation which is of data-type long. Parameters: The function does not accepts a single parameter. Return value: The function returns the value before increment operation is performed to the previous value.
Given these sets of requirements, I think that a volatile
long should be sufficient. The counter wouldn't be incorrect with a non-volatile
long, but the reader might be reading stale information in that case.
One problem is that reads and writes to a long
are not required to be atomic, by the JVM specification if it is not declared volatile
. That would mean that the reading thread could get a pretty much fictive value if it reads the value while the writing thread has updated one part of the value, but not the other one.
The difference between ++counter
and counter++
is probably irrelevant, as the JVM will realize that the value of the expression is not used any more and the two are equivalent in this case.
In Java 8, use LongAdder which is even better than AtomicLong where thread contention is high.
LongAdder JavaDoc:
This class is usually preferable to AtomicLong when multiple threads update a common sum that is used for purposes such as collecting statistics, not for fine-grained synchronization control. Under low update contention, the two classes have similar characteristics. But under high contention, expected throughput of this class is significantly higher, at the expense of higher space consumption.
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