Java Reference
In-Depth Information
Atomic variable classes are named like AtomicXxx , and can be used to execute multiple instructions on a single
variable atomically without using any lock. Here, Xxx is replaced with different words to indicate different classes that
are used for different purposes; for example, the AtomicInteger class is used to represent an int variable, which is
supposed to be manipulated atomically. Twelve classes in the Java class library support read-modify-write operations
on a single variable atomically. They are in the java.util.concurrent.atomic package. They can be categorized in
four categories, which will be discussed in the following sections.
Scalar Atomic Variable Classes
The AtomicInteger , AtomicLong , and AtomicBoolean classes support operations on primitive data types int , long ,
and boolean , respectively.
If you need to work with other primitive data types, use the AtomicInteger class. You can use it directly to work
with byte and short data types. Use it to work with the float data type by using the Float.floatToIntBits() method
to convert a float value to the int data type and the AtomicInteger.floatValue() method to convert an int value to
the float data type back.
You can use the AtomicLong class to work with the double data type by using the Double.doubleToLongBits()
method to convert a double value to the long data type and the AtomicLong.doubleValue() method to convert the
long value to the double data type.
The AtomicReference class is used to work with a reference data type when a reference variable needs to be
updated atomically.
Atomic Arrays Classes
There are three classes called AtomicIntegerArray , AtomicLongArray , and AtomicReferenceArray that represent an
array of int , long , and reference types whose elements can be updated atomically.
Atomic Field Updater Classes
There are three classes called AtomicLongFieldUpdater , AtomicIntegerFieldUpdater , and
AtomicReferenceFieldUpdater that can be used to update a volatile field of a class atomically using reflection.
These classes have no constructors. To get a reference to an object of these classes, you need to use their factory
method called newUpdater() .
Atomic Compound Variable Classes
CAS works by asking “Is the value at location M still O ?” If the answer is yes, it updates the value at location M from O to
N . In a typical scenario, one thread may read the value from location M as O . By the time this thread tries to update the
value from O to N , another thread has changed the value at location M from O to P , and back from P to O . Therefore, the
call CAS(M, O, N) will succeed because the value at location M is still O , even though it was changed ( O to P and back to
O ) twice after the thread read the value O last time. In some cases, it is fine. The thread that wants to update the value at
location M does not care if the old value O that it read last time was updated before its own update as long as the value
at location M is O at the time it is updating the value to N . However, in some cases, it is not acceptable. If a thread reads
the value O from a location M , this thread wants to make sure that after it read the value, no other thread has updated
the value. In such cases, CAS needs to ask “Has the value at location M changed since I last read it as O ?” To achieve this
functionality, you need to store a pair of values: the value you want to work with and its version number. Each update
will also update the version number. The AtomicMarkableReference and AtomicStampedReference classes fall into
this category of atomic compound variable class.
Let's look at a simple example that uses an atomic class. If you want to write a class to generate a counter using
built-in Java synchronization, it will resemble the code in Listing 6-28.
 
Search WWH ::




Custom Search