> Assuming that everything is done more-or-less perfectly, then when you
> have finished initializing the field, you can do what you
> said originally and make the shared reference to the object volatile. You
> can then read that reference *once* in the reader thread and copy it to a
> non-volatile local. After that, use the non-volatile local instead of the
> shared volatile. You only need to perform the memory barrier once, after
all.
Copying into a thread-local variable certainly avoids the overhead of using
either a volatile reference or a synchronized accessor to the reference, but
requires a different approach to the way things are typically done at
present. If access to the object is within a simple scope then it is
feasible to use a local stack-based variable to hold the thread-local copy.
In general however these shared variables tend to be accessed from various
methods in various classes - take the Singleton pattern as an example. In
that case the only way to get a thread-local copy is to use a real
ThreadLocal accessed via the Singleton class.
public class Singleton {
private static theInstance = null;
private ThreadLocal localInstance = new ThreadLocal();
public static Singleton getInstance() {
Singleton local = (Singleton) localInstance.get();
if (local == null) {
synchronized (Singleton.class) {
if (theInstance == null)
theInstance = new Singleton();
}
localInstance.set(theInstance);
return theInstance;
}
return local;
}
}
I wonder how the overhead of ThreadLocal compares to either a synchronized
accessor or a volatile reference. ;-)
Many of these situations boil down to what you describe: each thread needs
to get synchronized access to the reference to the shared object only the
first time they access it. Finding a way to pay for that synchronization
only once is one of the goals.
Cheers,
David
-------------------------------
JavaMemoryModel mailing list - http://www.cs.umd.edu/~pugh/java/memoryModel
This archive was generated by hypermail 2b29 : Thu Oct 13 2005 - 07:00:30 EDT