The classes AtomicBoolean, AtomicInteger, AtomicLong and AtomicReference enable the primitives boolean, int, long and an object reference to be atomically updated. They all provide utility methods like compareAndSet which takes an expected value and the update value and returns false if the expected value doesn't equal (==) the current value. The AtomicInteger and AtomicLong classes also provide atomic pre and post decrement/increment methods like getAndIncrement or incrementAndGet.
An example use of one of the 'scalar' atomic classes is shown below:
public class IdentifierGenerator { private AtomicLong seed = new AtomicLong(0); public long getNextIdentifier() { return seed.getAndIncrement(); } }
The int and long primitives, and also object references can be held in arrays where the elements are atomically updated namely AtomicIntegerArray, AtomicLongArray and AtomicReferenceArray.
There also exists field updater classes namely AtomicIntegerFieldUpdater, AtomicLongFieldUpdater and AtomicReferenceFieldUpdater. With these classes you can still use the methods on the class but use the updater class to manage the field that requires atomic access via methods like compareAndSet. Note that because of this, atomcity isn't guaranteed.
These are abstract classes and the below (contrived!) example shows how an instance would be created:
public void setBalance(Customer customer, int exisitngBalance, int newBalance) { AtomicIntegerFieldUpdater<Customer> balanceAccessor = AtomicIntegerFieldUpdater.newUpdater( Customer.class, "balance"); balanceAccessor.compareAndSet(customer, exisitngBalance, newBalance); }