Friday 25 March 2011

Thread-safe and lock free variables

The java.util.concurrent.atomic package contains classes which aim to ease concurrency concerns in multithreaded applications. They offer better performance than using synchronisation because its operations on fields do not require locking.

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);

    }

4 comments:

  1. I don't get this. Does it mean that an operation like int x = 12; isn't atomic anyway?

    ReplyDelete
  2. To answer my own question. Yes, int x = 12 is atomic, but many operations on ints, and especially longs and doubles, that look atomic are, in fact, not.
    To learn why the classes mentioned in this post are needed, read these:
    http://jeremymanson.blogspot.com/2007/08/volatile-does-not-mean-atomic.html
    http://jeremymanson.blogspot.com/2007/08/atomicity-visibility-and-ordering.html

    ReplyDelete
  3. Hi Does Atomicity has anything to do with 32 to 64 bit processor, I mean does atomicity changes when we move from one processor to other.

    Javin
    How HashMap works in Java

    ReplyDelete
  4. Hi Javin, Under the covers the primitve values of the Atomic classes are declared as volatile so there would be no change moving between 32 and 64 bit processors.

    ReplyDelete

Note: only a member of this blog may post a comment.