Close

Java - Atomic Field Updaters: AtomicReferenceFieldUpdater, AtomicIntegerFieldUpdater, and AtomicLongFieldUpdater

[Last Updated: May 22, 2018]

Field Updater classes can be used to perform atomic operation on a selected volatile field of a selected class.
AtomicReferenceFieldUpdater, AtomicIntegerFieldUpdater, and AtomicLongFieldUpdater are reflection-based utilities that provide access to the associated field types.

Example

We are going to use AtomicIntegerFieldUpdater. The updater instance can be created by using corresponding static factory method:

public static <U> AtomicIntegerFieldUpdater<U> newUpdater(Class<U> tclass,  String fieldName)
package com.logicbig.example;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;

public class AtomicFieldUpdaterExample {
    private static class Test {
        volatile int count;

        public int getCount() {
            return count;
        }
    }

    public static void main(String[] args) throws InterruptedException {
        AtomicIntegerFieldUpdater<Test> countFieldUpdater =
                AtomicIntegerFieldUpdater.newUpdater(Test.class, "count");
        Test test = new Test();

        ExecutorService es = Executors.newFixedThreadPool(5);
        for (int i = 0; i < 5; i++) {
            es.execute(() -> {
                for (int c = 0; c < 100; c++) {
                    countFieldUpdater.incrementAndGet(test);
                }
            });
        }
        es.shutdown();
        es.awaitTermination(10, TimeUnit.MINUTES);
        System.out.println("count: " + test.getCount());
    }
}
count: 500

When should we use atomic updater classes?

From Java docs:

These are mainly of use in atomic data structures in which several volatile 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.

To have a good understanding, following is a snippet taken from java.sql.SQLException which uses AtomicReferenceFieldUpdater (SQLException has a chain to a 'next' Exception which is used to provide additional error information coming from underlying database driver).

package java.sql;
  ....
public class SQLException extends java.lang.Exception implements ....{
  ....
private volatile SQLException next;

    private static final AtomicReferenceFieldUpdater<SQLException, SQLException> nextUpdater =
            AtomicReferenceFieldUpdater.newUpdater(SQLException.class, SQLException.class, "next");
  ......
 public void setNextException(SQLException ex) {
        SQLException current = this;
        for(;;) {
            SQLException next=current.next;
            if (next != null) {
                current = next;
                continue;
            }

            if (nextUpdater.compareAndSet(current, null, ex)) {
                return;
            }
            current=current.next;
        }
    }
............
 

Updater classes also allow to access fields directly (without any wrapper as in the case of say AtomicInteger). That means the operations which need not to be atomic, can access the field directly.

Example Project

Dependencies and Technologies Used:

  • JDK 10
  • Maven 3.3.9

Atomic Field Updater Example Select All Download
  • atomic-field-updater-example
    • src
      • main
        • java
          • com
            • logicbig
              • example
                • AtomicFieldUpdaterExample.java

    See Also