Home  Synchronization and concurrency  wait/notify  final  volatile  synchronized keyword  Java threading  Deadlock (and avoiding it)  Java 5: ConcurrentHashMap  Atomic variables  Explicit locks  Queues  Semaphores  CountDownLatch  CyclicBarrier

Synchronization under the hood, and why Java 5 improves it (ctd)

(Continued from our discussion of Java synchronization under the hood.)

Exposure of atomic instructions in Java 5

Having worked through this example, we can see that the synchronized block involves an awful lot of baggage just to increment an integer variable. And paradoxically, the underlying implementation actually uses a machine code instruction designed to atomically update an integer variable! Rather than using CAS instructions around a whole load of other lock housekeeping tasks, wouldn't it be great if we could just use a CAS instruction to update the count variable? That way we do away with having to waste memory and time on extra housekeeping variables and with having to ensure memory access conditions on variables that are never affected by trhe critical block of code. In the worst case, our code just loops a couple of times rather than being context-switched out for several milliseconds to wait for a simple variable increment. Java 5 effectively allows this.

The big synchronization breakthrough in Java 5 is that it effectively exposes atomic instructions such as CAS to the Java programmer. The java.util.concurrent package contains the AtomicInteger class (and similar classes for other data types) allowing us to atomically compare-and-set an integer (and variants such as increment-and-get, set-and-get etc). Classes such as AtomicInteger are essentially wrappers around atomic machine code instructions such as CAS.

For a simple counter class such as the one above, we can pretty much use AtomicInteger as a drop-in replacement. But what's even more interesting is that Java 5 includes a whole host of other synchronization and concurrency classes already built around this new atomic functionality.

On the next page, we start our of Java 5 concurrency features by looking at the atomic classes in Java 5.

Tightening up of volatile and final

The introduction of non-blocking atomic variable access is a key part of the Java 5 concurrency improvements. Another improvement which is easy to miss is that the definitions of volatile and final have been tightened up slightly in order to allow them to be used with a couple of common programming idioms: lazy initialisation and immutable objects. As of Java 5:

  • Access to volatile variables have the same memory synchronization and ordering behaviour as synchronized blocks.
  • If an instance variable is declared final and its value set in the constructor, that set value is guaranteed to be seen by another thread as soon as it can see the object that holds that variable. This means that we don't need synchronization to access an object for which all fields are final.

We'll look at what this means in more detail below, but first let's get back to the atomic classes.

Article written by Neil Coffey (@BitterCoffey).

Software

 LetterMeister (word puzzle game for iPhone)
 Currency Quoter (currency converter/predictor)
 French Vocab Games for iPhone/iPad
 Vocabularium: create Spanish vocab podcasts


Java programming articles and tutorials on this site are written by Neil Coffey (@BitterCoffey). Suggestions are always welcome if you wish to suggest topics for Java tutorials or programming articles, or if you simply have a programming question that you would like to see answered on this site. Most topics will be considered. But in particular, the site aims to provide tutorials and information on topics that aren't well covered elsewhere, or on Java performance information that is poorly described or understood. Suggestions may be made via the Javamex blog (see the site's front page for details).
Copyright © Neil Coffey 2015. All rights reserved.