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