>
> 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. ;-)
It is implemented as a synchronizedMap in Sun's JDK, IIRC.
>
> 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.
Seems to me that you could associate the barrier with an instance of the
thread object. It isn't nice and object-oriented (and I can hear the
cries of pain now), but it would work. Consider the following.
class myThread extends Thread {
public Singleton initSynch;
}
public class Singleton {
private static Singleton theInstance = null;
public static Singleton getInstance() {
myThread thisThread = (myThread) Thread.currentThread();
Singleton local = thisThread.initSynch;
if (local == null) {
synchronized (Singleton.class) {
if (theInstance == null)
theInstance = new Singleton();
}
thisThread.initSynch = theInstance;
return theInstance;
}
return local;
}
}
I would certainly discourage this as bad style, but it gets around the
synchronization issue. A slightly better style, which confuses the
example, and makes it slower, would have a hashTable of references (or
something) in myThread. The abstraction there would be something like
"this table is a list of all initialized read-only objects the thread
can use". That adds overhead, but not the same overhead as a
synchronizedMap (probably).
Jeremy
-------------------------------
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