< prev index next >

src/java.base/share/classes/java/lang/ThreadLocal.java

Print this page




   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.lang;


  27 import java.lang.ref.*;
  28 import java.util.Objects;
  29 import java.util.concurrent.atomic.AtomicInteger;
  30 import java.util.function.Supplier;
  31 
  32 /**
  33  * This class provides thread-local variables.  These variables differ from
  34  * their normal counterparts in that each thread that accesses one (via its
  35  * {@code get} or {@code set} method) has its own, independently initialized
  36  * copy of the variable.  {@code ThreadLocal} instances are typically private
  37  * static fields in classes that wish to associate state with a thread (e.g.,
  38  * a user ID or Transaction ID).
  39  *
  40  * <p>For example, the class below generates unique identifiers local to each
  41  * thread.
  42  * A thread's id is assigned the first time it invokes {@code ThreadId.get()}
  43  * and remains unchanged on subsequent calls.
  44  * <pre>
  45  * import java.util.concurrent.atomic.AtomicInteger;
  46  *


 154      * current thread, it is first initialized to the value returned
 155      * by an invocation of the {@link #initialValue} method.
 156      *
 157      * @return the current thread's value of this thread-local
 158      */
 159     public T get() {
 160         Thread t = Thread.currentThread();
 161         ThreadLocalMap map = getMap(t);
 162         if (map != null) {
 163             ThreadLocalMap.Entry e = map.getEntry(this);
 164             if (e != null) {
 165                 @SuppressWarnings("unchecked")
 166                 T result = (T)e.value;
 167                 return result;
 168             }
 169         }
 170         return setInitialValue();
 171     }
 172 
 173     /**













 174      * Variant of set() to establish initialValue. Used instead
 175      * of set() in case user has overridden the set() method.
 176      *
 177      * @return the initial value
 178      */
 179     private T setInitialValue() {
 180         T value = initialValue();
 181         Thread t = Thread.currentThread();
 182         ThreadLocalMap map = getMap(t);
 183         if (map != null)
 184             map.set(this, value);
 185         else
 186             createMap(t, value);

 187         return value;
 188     }
 189 
 190     /**
 191      * Sets the current thread's copy of this thread-local variable
 192      * to the specified value.  Most subclasses will have no need to
 193      * override this method, relying solely on the {@link #initialValue}
 194      * method to set the values of thread-locals.
 195      *
 196      * @param value the value to be stored in the current thread's copy of
 197      *        this thread-local.
 198      */
 199     public void set(T value) {
 200         Thread t = Thread.currentThread();
 201         ThreadLocalMap map = getMap(t);
 202         if (map != null)
 203             map.set(this, value);
 204         else
 205             createMap(t, value);
 206     }




   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.lang;
  27 import jdk.internal.misc.TerminatingThreadLocal;
  28 
  29 import java.lang.ref.*;
  30 import java.util.Objects;
  31 import java.util.concurrent.atomic.AtomicInteger;
  32 import java.util.function.Supplier;
  33 
  34 /**
  35  * This class provides thread-local variables.  These variables differ from
  36  * their normal counterparts in that each thread that accesses one (via its
  37  * {@code get} or {@code set} method) has its own, independently initialized
  38  * copy of the variable.  {@code ThreadLocal} instances are typically private
  39  * static fields in classes that wish to associate state with a thread (e.g.,
  40  * a user ID or Transaction ID).
  41  *
  42  * <p>For example, the class below generates unique identifiers local to each
  43  * thread.
  44  * A thread's id is assigned the first time it invokes {@code ThreadId.get()}
  45  * and remains unchanged on subsequent calls.
  46  * <pre>
  47  * import java.util.concurrent.atomic.AtomicInteger;
  48  *


 156      * current thread, it is first initialized to the value returned
 157      * by an invocation of the {@link #initialValue} method.
 158      *
 159      * @return the current thread's value of this thread-local
 160      */
 161     public T get() {
 162         Thread t = Thread.currentThread();
 163         ThreadLocalMap map = getMap(t);
 164         if (map != null) {
 165             ThreadLocalMap.Entry e = map.getEntry(this);
 166             if (e != null) {
 167                 @SuppressWarnings("unchecked")
 168                 T result = (T)e.value;
 169                 return result;
 170             }
 171         }
 172         return setInitialValue();
 173     }
 174 
 175     /**
 176      * Returns {@code true} if there is a value in the current thread's copy of
 177      * this thread-local variable, even if that values is {@code null}.
 178      *
 179      * @return {@code true} if current thread has associated value in this
 180      *         thread-local variable; {@code false} if not
 181      */
 182     boolean isPresent() {
 183         Thread t = Thread.currentThread();
 184         ThreadLocalMap map = getMap(t);
 185         return map != null && map.getEntry(this) != null;
 186     }
 187 
 188     /**
 189      * Variant of set() to establish initialValue. Used instead
 190      * of set() in case user has overridden the set() method.
 191      *
 192      * @return the initial value
 193      */
 194     private T setInitialValue() {
 195         T value = initialValue();
 196         Thread t = Thread.currentThread();
 197         ThreadLocalMap map = getMap(t);
 198         if (map != null)
 199             map.set(this, value);
 200         else
 201             createMap(t, value);
 202         TerminatingThreadLocal.register(this);
 203         return value;
 204     }
 205 
 206     /**
 207      * Sets the current thread's copy of this thread-local variable
 208      * to the specified value.  Most subclasses will have no need to
 209      * override this method, relying solely on the {@link #initialValue}
 210      * method to set the values of thread-locals.
 211      *
 212      * @param value the value to be stored in the current thread's copy of
 213      *        this thread-local.
 214      */
 215     public void set(T value) {
 216         Thread t = Thread.currentThread();
 217         ThreadLocalMap map = getMap(t);
 218         if (map != null)
 219             map.set(this, value);
 220         else
 221             createMap(t, value);
 222     }


< prev index next >