Atomic field updaters

The Java 5 atomic classes also include atomic field updaters. These are essentially used as "wrappers" around a volatile field (primitive or object reference). In truth, these wrappers are used inside the Java class libraries, but probably aren't used much in user code. But it is worth taking a look at them to see when they could be useful. They are generally used when one or both of the following are true:

An example of the first kind is BufferedInputStream. Every instance of BufferedInputStream contains an internal buffer, defined as a volatile byte array. Generally speaking, BufferedInputStream just needs to refer to this array "normally" for the purpose of reading/writing bytes. However, an atomic get-and-set operation is needed in specific places where the buffer array is replaced (either to grow it or to mark it as null or closed), because closure can occur in a different thread to that performing the reads. One option would have been to declare the buffer variable as an AtomicReference to an array, and always get and set the array via this variable. But that would be a bit messy. Instead, a noraml volatile array variable is used, and the class also contains a static AtomicReferenceUpdater as follows:

static AtomicReferenceFieldUpdater<BufferedInputStream, byte[]>
  bufUpdater = AtomicReferenceFieldUpdater.newUpdater
        (BufferedInputStream.class,  byte[].class, "buf");

The array itself still remains a normal (volatile) variable, and reads and writes from the array can use normal array syntax. But when necessary, via the field updater, an atomic compare-and-set operation can be performed on the volatile variable. Although the updater is static, each instance of BufferedInputStream has its own buffer of course. So when we perform the CAS operation, we need to pass into the updater the actual object whose variable we want to affect:

if (bufUpdater.compareAndSet(this, oldBuffer, newBuffer)) {
  ...
}

This is a call inside a method of BufferedInputStream, so this refers to the particular instance of this class that the method is being called on, and that object's variable will be affected.

Using atomic field updaters for linked nodes

Another use for atomic field updaters is to avoid creating a large number of spurious atomic variables. For example, if we were creating a linked list structure designed for concurrent access, we might want each node to have an atomic variable pointing to the next node in the list. Judicious code can then allow different parts of the list to be updated concurrently. Without atomic field updaters, this would have meant code such as the following:

public class Node<T> {
  private AtomicReference<Node<T>> next;
  private T val;
  ...
}

In other words, every single node will have an additional AtomicReference object embedded in it. Using an atomic field updater, we can get a performance gain by declaring the 'next node' variable as a normal volatile object reference, and then using a field updater (of which we declare a single, static, instance shared by all nodes to access their respective 'next node' field):

public class Node<T> {
  private volatile Node<T> next;
  private T val;
  ...
}

As mentioned, atomic field updaters have been used in various places in the Java class libraries. In reality, if you want an efficient currently accessible data structure, it is strongly recommended to use one of the excellent standard implementations such as ConcurrentHashMap, ConcurrentLinkedQueue or (as of Java 6) ConcurrentSkipListMap.

Next...

On the next page, we move on to look at Java 5's concurrent collections, with arguably the most important, the ConcurrentHashMap class.


If you enjoy this Java programming article, please share with friends and colleagues. Follow the author on Twitter for the latest news and rants.

Editorial page content written by Neil Coffey. Copyright © Javamex UK 2021. All rights reserved.