boolean attemptUpdate(expectedValue, updateValue);
This method (which varies in argument types across different
classes) is used to atomically set a variable to the
updateValue
if it currently holds the
expectedValue
, reporting true
on success.
Calls to attemptUpdate
should almost always appear in
loops of some sort. Any given invocation of
attemptUpdate
method may fail, even spuriously (that is,
for no apparent reason). A false
return means only that
the operation may be retried if desired, relying on the guarantee that
repeated invocation when the variable holds expectedValue
and no other thread is also attempting to set the variable will
eventually succeed.
This specification of attemptUpdate
enables
implementations to employ efficient machine-level atomic instructions
that are available on contemporary processors. However on some
platforms support may entail some form of internal locking. Thus the
method is not strictly guaranteed to be non-blocking.
Method attemptUpdate
, along with method
get
that returns current value, minimally suffice for
programming with atomic operations. The classes and methods in this
package provide a few related operations to form a small toolkit of
common constructions using atomics.
Instances of classes AtomicBoolean
,
AtomicInteger
, AtomicLong
, and
AtomicReference
each provide access and updates to a
single variable of the corresponding type. The memory effects for
accesses and updates are exactly the same as those of
volatile
fields. Each class also provides appropriate
utility methods for that type. For example, AtomicLong
and AtomicInt
provide an atomic increment method. One
application is to generate sequence numbers, as in:
class Sequencer { private AtomicLong sequenceNumber = new AtomicLong(0); public long next() { return sequenceNumber.getAndIncrement(); } }
Atomic references find use in constructions that require additional
utility classes, not utility methods. The
AtomicMarkableReference
class associates a single boolean
with a reference. For example, this bit might be used inside a data
structure to mean that the object being referenced has logically been
deleted. The AtomicStampedReference
class associates an
integer value with a reference. This may be used for example, to
represent version numbers corresponding to series of updates.
Finally, AtomicReferenceFieldUpdater
is a
reflection-based utility that enables atomic updates to designated
reference fields of designated classes. It may be of use in atomic
data structures in which several reference fields of the same node
(for example, the links of a tree node) are independently subject to
atomic updates. This class enables greater flexibility in how and when
to use atomic updates, at the expense of more awkward reflection-based
setup, less convenient usage, and weaker guarantees.
Atomics are not used very often in application-level classes. They
are designed primarily as building blocks for implementing
non-blocking data structures and related infrastructure classes. The
attemptUpdate
method is not a general replacement for
locking. It applies only when critical updates for an object are
confined to a single variable. And atomic classes are not
general purpose replacements for java.lang.Integer
,
java.lang.Boolean
and related classes. They do
NOT define methods such as hashCode
and
compareTo
. (Because atomic variables are expected to be
mutated, they are poor choices for hash table keys.) Additionally,
classes are provided only for those types that are commonly useful as
atomics. For example, there is no atomic class for representing
byte
. In those infrequent cases where you would like to
do so, you can use an AtomicInteger
to hold
byte
values, and cast appropriately. Similarly, you can
hold floating point types using Float.floatToIntBits
and
Float.intBitstoFloat
conversions.