Synchronized as volatile replacement: part I

November 3, 2008

I was looking at the source code of Quartz (the SimpleThreadpool to be specific) and I noticed that synchronized blocks are used to access a single variable (read/write) instead of declaring the variable volatile.

//write: runnable is a object field.
synchronized(this) {
	runnable = null;
}

//read: run is an object field, shouldRun is a local variable.              
synchronized(this) {
	shouldRun = run;
}

The main purpose of these synchronized blocks, next to preventing reordering problems, is the prevent visibility problems: each reading thread that uses some lock, will see the most recently written value, written under the same lock. If the synchronized blocks are missing, one thread doesn’t need to see the changes made by another thread, because values can be stuck in the cache of a cpu for example. So synchronized blocks are a legit way to let threads exchange information.

But this can just as easily be achieved by declaring the variable volatile because the lock.release/lock.acquire (monitor lock rule) has the same JMM properties as a volatile.write and a volatile.read (the volatile variable rule). So if there are no invariants that can break by early publication of some state value, I prefer volatiles over synchronized blocks for publication for the following reasons:

  1. once declared volatile, each variable access will be protected. With synchronized locks it is easy to forget because you need to rely on a convention (that often isn’t documented or well understood).
  2. volatiles are lightweight, and won’t lead to Operating System calls unlike locks. Although JVM optimizations like biased locking and adaptive spin locking can reduce the actual number of Operating System calls. For more information about lock optimizations you could have a look at the following article on InfoQ article written by Jeroen Borders, a colleague.

In some cases you can even combine volatiles with locks: if the early publication of the variable doesn’t break invariants, but a change to that variable needs to be done atomic in combination with others.

In the next blogpost I will explain that synchronized blocks are a little bit more strict than volatiles variables.

Advertisements

Speaking at JFall about the JMM

November 3, 2008

At 12 November I’ll be speaking at JFall about the Java Memory Model. This is my first presentation for a large crowd, but this year I have been speaking at least once a month at my employer about mostly concurrency related subjects (low level concurrency, java memory model , java.util.concurrent, databases, architecture and concurrency, fork join framework, mvcc, stm). A few days later I’ll be giving a similar presentation at the IB-groep. Eventually my goal is to give presentations on large international (Java) conferences to become a concurrency authority, and this should help me to get the cool assignments.

So if you want to know more about the JMM, go to my presentation and don’t hesitate to ask questions.

[edit]
If you want to see my presentation (Dutch), you can check it here:
http://www.bachelor-ict.nl/peter-veentjer