Is anybody aware of any real life use of the class AtomicLongFieldUpdate? I have read the description but I have not quite grasped the meaning of it. Why do I want to know that? Curiosity and for OCPJP preparation.
Thanks in advance.
Is anybody aware of any real life use of the class AtomicLongFieldUpdate? I have read the description but I have not quite grasped the meaning of it. Why do I want to know that? Curiosity and for OCPJP preparation.
Thanks in advance.
You can think of a cost ladder for the following:
long
: cheap, but unsafe for multi-threaded accessvolatile long
: more expensive, safe for multi-threaded access, atomic operations not possibleAtomicLong
: most expensive, safe for multi-threaded access, atomic operations possible(When I say 'unsafe' or 'not possible' I mean 'without an external mechanism like synchronization' of course.)
In the case where multi-threaded access is needed, but most operations are simple reads or writes, with only a few atomic operations needed, you can create one static instance of AtomicLongFieldUpdate
and use this when atomic updates are needed. The memory/runtime overhead is then similar to a simple volatile
variable, except for the atomic operations which are of the order of (or slightly more expensive than) the ordinary AtomicLong
operations.
Here is a nice little tutorial.
AtomicLong
is only more "expensive" than volatile long
in that there is a wrapper class -- so slightly more memory overhead. Also, volatile long
is not "safe for multi-threaded access` if you are doing ++
. –
Congenital AtomicLongFieldUpdate
us going to be much more than just a simple AtomicLong
. And the runtime is going to be slower than both volatile long
and AtomicLong
since it is using reflection. –
Congenital sun.misc.Unsafe
for the real compareAndSet
- so the set up is more expensive, but I would expect the runtime cost to just a bit higher than ordinary AtomicLong
. –
Hendershot The reason why you would use e.g. AtomicLongFieldUpdater in favor to AtomicLong is simply to reduce the heap cost. Internally both work pretty much the same on th compareAndSet level which both use sun.misc.Unsafe at the end.
Consider you have a certain class that is initialized 1000k times. With AtomicLong you'd create 1000k AtomicLongs. With AtomicLongFieldUpdater on the other hand, you'd create 1 CONSTANT AtomicLongFieldUpdater and 1000k long primitives which of course does not need so much heap space.
Is anybody aware of any real life use of the
AtomicLongFieldUpdate
class?
I've never used this class myself but in doing a get usage on my workspace I see a couple "real life" instances of its use:
com.google.common.util.concurrent.AtomicDouble
uses it to atomically modify their internal volatile long
field which stores the bits from a double
using Number.doubleToRawLongBits(...)
. Pretty cool.
net.sf.ehcache.Element
uses it to atomically update the hitCount
field.
I have read the description but I have not quite grasped the meaning of it.
It basically provides the same functionality as AtomicLong
but on a field local to another class. The memory load of the AtomicLongFieldUpdate
is less than the AtomicLong
in that you configure one instance of the update for each field so lower memory overhead but more CPU overhead (albeit maybe small) from the reflection.
The javadocs say:
This class is designed for use in atomic data structures in which several fields of the same node are independently subject to atomic updates.
Sure but then I'd just use multiple Atomic*
fields. Just about the only reason why I'd use the class is if there was an existing class that I could not change that I wanted to increment atomically.
Of course. I have been reading Alibaba Druid recently. I found AtomicLongFieldUpdater
is used in this project widely.
// stats
private volatile long recycleErrorCount = 0L;
private volatile long connectErrorCount = 0L;
protected static final AtomicLongFieldUpdater<DruidDataSource> recycleErrorCountUpdater
= AtomicLongFieldUpdater.newUpdater(DruidDataSource.class, "recycleErrorCount");
protected static final AtomicLongFieldUpdater<DruidDataSource> connectErrorCountUpdater
= AtomicLongFieldUpdater.newUpdater(DruidDataSource.class, "connectErrorCount");
As defined above, the properties recycleErrorCount
and connectErrorCount
are used to count error occurrence times.
Quite a lot of DataSource
(The class that holds properties above) will be created during an application lifetime in which case using ALFU
reduces heap space consumption obviously than using AtomicLong
.
Atomics are usually used in parallel programming.
Under the work-stealing mode, it only supports async, finish, forasync, isolated, and atomic variables.
You can view atomic as a safe protection from data race and other problems that you need to concern in parallel programming.
AtomicLongFieldUpdate
. –
Congenital © 2022 - 2024 — McMap. All rights reserved.
AtomicLongFieldUpdater
, notAtomicLongFieldUpdate
! :) – Machiavellian