/[classpath]/classpath/java/lang/ThreadLocal.java
ViewVC logotype

Diff of /classpath/java/lang/ThreadLocal.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.2 by mark, Tue Jan 22 22:27:00 2002 UTC revision 1.3 by ericb, Wed Mar 20 20:04:32 2002 UTC
# Line 1  Line 1 
1  /* java.lang.ThreadLocal  /* ThreadLocal -- a variable with a unique value per thread
2     Copyright (C) 2000 Free Software Foundation, Inc.     Copyright (C) 2000, 2002 Free Software Foundation, Inc.
3    
4  This file is part of GNU Classpath.  This file is part of GNU Classpath.
5    
# Line 7  GNU Classpath is free software; you can Line 7  GNU Classpath is free software; you can
7  it under the terms of the GNU General Public License as published by  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2, or (at your option)  the Free Software Foundation; either version 2, or (at your option)
9  any later version.  any later version.
10    
11  GNU Classpath is distributed in the hope that it will be useful, but  GNU Classpath is distributed in the hope that it will be useful, but
12  WITHOUT ANY WARRANTY; without even the implied warranty of  WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Line 46  import java.util.WeakHashMap; Line 46  import java.util.WeakHashMap;
46   * (through the <code>get()</code> and <code>set()</code> methods)   * (through the <code>get()</code> and <code>set()</code> methods)
47   * only affects the state of the object as seen by the currently   * only affects the state of the object as seen by the currently
48   * executing Thread.   * executing Thread.
49   * <p>   *
50   * The first time a ThreadLocal object is accessed on a particular   * <p>The first time a ThreadLocal object is accessed on a particular
51   * Thread (and no state is associated with that Thread yet)   * Thread, the state for that Thread's copy of the local variable is set by
52   * the state for that Thread is set by executing the method   * executing the method <code>initialValue()</code>.
53   * <code>initialValue()</code>.   *
54   * <p>   * <p>An example how you can use this:
  * An example how you can use this:  
55   * <pre>   * <pre>
56   * class Connection {   * class Connection
57   *     private static ThreadLocal owner = new ThreadLocal() {   * {
58   *        public Object initialValue() {   *   private static ThreadLocal owner = new ThreadLocal()
59   *            return("nobody");   *     {
60   *        }   *       public Object initialValue()
61     *       {
62     *         return("nobody");
63     *       }
64   *     };   *     };
65   * ...   * ...
66   * }   * }
67   * </pre>   * </pre></br>
68     *
69   * Now all instances of connection can see who the owner of the currently   * Now all instances of connection can see who the owner of the currently
70   * executing Thread is by calling <code>owner.get()</code>. By default any   * executing Thread is by calling <code>owner.get()</code>. By default any
71   * Thread would be associated with 'nobody'. But the Connection object could   * Thread would be associated with 'nobody'. But the Connection object could
72   * offer a method that changes the owner associated with the Thread on   * offer a method that changes the owner associated with the Thread on
73   * which the method was called by calling <code>owner.put("somebody")</code>.   * which the method was called by calling <code>owner.put("somebody")</code>.
74   * (Such an owner changing method should then be guarded by security checks.)   * (Such an owner changing method should then be guarded by security checks.)
75   * <p>   *
76   * When a Thread is garbage collected all references to values of   * <p>When a Thread is garbage collected all references to values of
77   * the ThreadLocal objects associated with that Thread are removed.   * the ThreadLocal objects associated with that Thread are removed.
78   *   *
79     * @author Mark Wielaard <mark@klomp.org>
80     * @author Eric Blake <ebb9@email.byu.edu>
81   * @since 1.2   * @since 1.2
82   * @author Mark Wielaard (mark@klomp.org)   * @status updated to 1.4
83   */   */
84  public class ThreadLocal {  public class ThreadLocal
85            {
86          /**    /**
87           * Trivial container to wrap the stored values.     * Placeholder to distinguish between uninitialized and null set by the
88           * Needed to see if the value is null or not yet set.     * user. Do not expose this to the public. Package visible for use by
89           * If it is not yet set we must call intialValue() once.     * InheritableThreadLocal
90           * Package local so InheritableThreadLocal can see it.     */
91           */    static final Object NULL = new Object();
92          final static class Value {  
93                  final Object value;    /**
94                       * The stored value. Package visible for use by InheritableThreadLocal. */
95                  Value(Object value) {    Object value;
96                          this.value = value;          
97                  }    /**
98                       * Maps Threads to values. Uses a WeakHashMap so if a Thread is garbage
99                  Object getValue() {     * collected the reference to the Value will disappear. A null value means
100                          return value;     * uninitialized, while NULL means a user-specified null. Only the
101                  }     * <code>set(Thread, Object)</code> and <code>get(Thread)</code> methods
102          }     * access it. Package visible for use by InheritableThreadLocal.
103               */
104          /**    final Map valueMap = new WeakHashMap();
105           * Maps Threads to Values. Uses a WeakHashMap so if a Thread is garbage          
106           * collected the reference to the Value will disappear. Only the    /**
107           * <code>set(Thread, Value)</code> and <code>get(Thread)</code> methods     * Creates a ThreadLocal object without associating any value to it yet.
108           * access it. Since this can happen from multiple Threads simultaniously     */
109           * those methods are synchronized.    public ThreadLocal()
110           */    {
111          private final Map valueMap = new WeakHashMap();    }
112            
113          /**    /**
114           * Creates a ThreadLocal object without associating any value to it     * Called once per thread on the first invocation of get(), if set() was
115           * yet.     * not already called. The default implementation returns <code>null</code>.
116           */     * Often, this method is overridden to create the appropriate initial object
117          public ThreadLocal() {     * for the current thread's view of the ThreadLocal.
118          }     *
119               * @return the initial value of the variable in this thread
120          /**     */
121           * Gets the value associated with the ThreadLocal object for the    protected Object initialValue()
122           * currently executing Thread. If there is no value is associated    {
123           * with this Thread yet then the valued returned by the      return null;
124           * <code>initialValue()</code> method is assosiated with this Thread    }
125           * and returned.  
126           */    /**
127          public Object get() {     * Gets the value associated with the ThreadLocal object for the currently
128                  Thread currentThread = Thread.currentThread();     * executing Thread. If this is the first time the current thread has called
129                  Value v = get(currentThread);     * get(), and it has not already called set(), the value is obtained by
130                  if (v == null) {     * <code>initialValue()</code>.
131                          v = new Value(initialValue());     *
132                          set(currentThread, v);     * @return the value of the variable in this thread
133                  }     */
134                  return v.getValue();    public Object get()
135          }    {
136                Thread currentThread = Thread.currentThread();
137          /**      // Note that we don't have to synchronize, as only this thread will
138           * Gets the Value of this ThreadLocal for a particular Thread.      // ever modify the returned value.
139           * It is synchronized so the <code>set(Thread, Value)</code> method cannot      Object value = valueMap.get(currentThread);
140           * simultaniously modify the </code>valueMap</code> from another thread.      if (value == null)
141           * Package local so InheritableThreadLocal can access it when a new child        {
142           * Thread inherits values from its parent Thread.          value = initialValue();
143           */          valueMap.put(currentThread, value == null ? NULL : value);
144          synchronized final Value get(Thread thread) {        }
145                  return (Value)valueMap.get(thread);      return value == NULL ? null : value;
146          }    }
147            
148          /**    /**
149           * Sets the value associated with the ThreadLocal object for the     * Sets the value associated with the ThreadLocal object for the currently
150           * currently executing Thread. This overrides any existing value     * executing Thread. This overrides any existing value associated with the
151           * associated with the current Thread and does not call the     * current Thread and prevents <code>initialValue()</code> from being
152           * <code>initialValue()</code> method, even if this is the first     * called if this is the first access to this ThreadLocal in this Thread.
153           * time this Thread accesses this ThreadLocal.     *
154           */     * @param value the value to set this thread's view of the variable to
155          public void set(Object value) {     */
156                  Thread currentThread = Thread.currentThread();    public void set(Object value)
157                  Value v = new Value(value);    {
158                  set(currentThread, v);      // Note that we don't have to synchronize, as only this thread will
159          }      // ever modify the returned value.
160                valueMap.put(Thread.currentThread(), value == null ? NULL : value);
161          /**    }
          * Sets the Value for this ThreadLocal for a particular Thread.  
          * It is synchronized so the <code>get(Thread)</code> method cannot  
          * simultaniously read the </code>valueMap</code> from another thread.  
          * Package local so InheritableThreadLocal can access it when a new child  
          * Thread inherits values from its parent Thread.  
          */  
         synchronized final void set(Thread thread, Value value) {  
                 valueMap.put(thread, value);  
         }  
           
         /**  
          * Called when <code>get()</code> is called and no state is associated  
          * with the currently executing Thread yet.  
          * <p>  
          * The default implementation returns <code>null</code>.  
          */  
         protected Object initialValue() {  
                 return null;  
         }  
162  }  }

Legend:
Removed from v.1.2  
changed lines
  Added in v.1.3

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26