boolean compareAndSet(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.
The classes additionally support a weaker version of this operation:
boolean weakCompareAndSet(expectedValue, updateValue);This method may be more efficient in the normal case, but differs in that any given invocation of
weakCompareAndSet
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.
The specifications of these methods enable 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 methods are not strictly guaranteed to be non-blocking.
Method compareAndSet
, 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(); } }
In addition to classes representing single values, this package
also contains Updater classes that can be used to obtain
compareAndSwap operations on any selected volatile field of any
selected class. AtomicReferenceFieldUpdater
,
AtomicIntegerFieldUpdater
, and
AtomicLongFieldUpdater
are reflection-based utilities
that perform atomic updates to designated reference fields of
designated classes. They are mainly 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. These classes enable 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.
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,
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
compareAndSet
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.