Java - Thread Atomic Variables

Introduction

Atomic variable classes executes multiple instructions on a single variable atomically without using any lock.

Twelve classes in java.util.concurrent.atomic package support read-modify-write operations on a single variable atomically.

They can be categorized in four categories.

  • Scalar Atomic Variable Classes
  • Atomic Arrays Classes
  • Atomic Field Updater Classes
  • Atomic Compound Variable Classes

Scalar Atomic Variable Classes

AtomicInteger, AtomicLong, and AtomicBoolean classes support operations on primitive data types int, long, and boolean, respectively.

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.

AtomicLong class works 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

AtomicIntegerArray, AtomicLongArray, and AtomicReferenceArray represent an array of int, long, and reference types whose elements can be updated atomically.

Atomic Field Updater Classes

AtomicLongFieldUpdater, AtomicIntegerFieldUpdater, and AtomicReferenceFieldUpdater updates a volatile field of a class atomically using reflection.

These classes have no constructors.

To create an object of these classes, use their factory method called newUpdater().

Example

To write a class to generate a counter using built-in Java synchronization

class SynchronizedCounter {
        private long value;

        public synchronized long next() {
                return ++value;
        }
}

You can rewrite the SynchronizedCounter class using the AtomicLong class.

class AtomicCounter {
        private AtomicLong value = new AtomicLong(0L);

        public long next() {
                return value.incrementAndGet();
        }
}

AtomicCounter class does not use any explicit synchronization.

incrementAndGet() method of the AtomicLong class increments its current value and returns the new value.