- /*
 - * @(#)ThreadLocal.java 1.16 00/02/02
 - *
 - * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved.
 - *
 - * This software is the proprietary information of Sun Microsystems, Inc.
 - * Use is subject to license terms.
 - *
 - */
 - package java.lang;
 - import java.util.*;
 - /**
 - * This class provides ThreadLocal variables. These variables differ from
 - * their normal counterparts in that each thread that accesses one (via its
 - * get or set method) has its own, independently initialized copy of the
 - * variable. ThreadLocal objects are typically private static variables in
 - * classes that wish to associate state with a thread (e.g., a user ID or
 - * Transaction ID).
 - *
 - * <p>Each thread holds an implicit reference to its copy of a ThreadLocal
 - * as long as the thread is alive and the ThreadLocal object is accessible;
 - * after a thread goes away, all of its copies of ThreadLocal variables are
 - * subject to garbage collection (unless other references to these copies
 - * exist).
 - *
 - * @author Josh Bloch
 - * @version 1.16, 02/02/00
 - * @since 1.2
 - */
 - public class ThreadLocal {
 - /**
 - * Initial capacity of per-thread HashMap from ThreadLocal to value.
 - * The size should be approximately twice the the number of thread local
 - * variables that thread might have.
 - */
 - private static final int INITIAL_CAPACITY = 11;
 - /**
 - * Creates a ThreadLocal variable.
 - */
 - public ThreadLocal() {
 - key = new SecureKey();
 - }
 - /**
 - * Secure key representing this thread local variable. This key is used
 - * in preference to the ThreadLocal object itself, to map this variable to
 - * its per-thread value, to prevent an attacker from overriding the equals
 - * method to spoof another ThreadLocal and steal its value.
 - */
 - Object key;
 - /**
 - * Returns the calling thread's initial value for this ThreadLocal
 - * variable. This method will be called once per accessing thread for
 - * each ThreadLocal, the first time each thread accesses the variable
 - * with get or set. If the programmer desires ThreadLocal variables
 - * to be initialized to some value other than null, ThreadLocal must
 - * be subclassed, and this method overridden. Typically, an anonymous
 - * inner class will be used. Typical implementations of initialValue
 - * will call an appropriate constructor and return the newly constructed
 - * object.
 - *
 - * @return the initial value for this ThreadLocal
 - */
 - protected Object initialValue() {
 - return null;
 - }
 - /**
 - * Returns the value in the calling thread's copy of this ThreadLocal
 - * variable. Creates and initializes the copy if this is the first time
 - * the thread has called this method.
 - *
 - * @return the value of this ThreadLocal
 - */
 - public Object get() {
 - Thread ourThread = Thread.currentThread();
 - Map map = ourThread.threadLocals;
 - Object value = map.get(key);
 - if (value==null && !map.containsKey(key)) {
 - if (map == Collections.EMPTY_MAP)
 - map = ourThread.threadLocals = new HashMap(INITIAL_CAPACITY);
 - value = initialValue();
 - map.put(key, value);
 - }
 - return value;
 - }
 - /**
 - * Sets the calling thread's instance of this ThreadLocal variable
 - * to the given value. This is only used to change the value from
 - * the one assigned by the initialValue method, and many applications
 - * will have no need for this functionality.
 - *
 - * @param value the value to be stored in the calling threads' copy of
 - * this ThreadLocal.
 - */
 - public void set(Object value) {
 - Thread ourThread = Thread.currentThread();
 - Map map = ourThread.threadLocals;
 - if (map == Collections.EMPTY_MAP)
 - map = ourThread.threadLocals = new HashMap(INITIAL_CAPACITY);
 - map.put(key, value);
 - }
 - /**
 - * An object of this class is used in place of the ThreadLocal itself
 - * as a key in the per-Thread ThreadLocal->value Map. This prevents
 - * a "spoof attack" where one ThreadLocal pretends to be another
 - * by overriding the equals (and hashCode) method and returning true
 - * when it should return false.
 - *
 - * The sole method (which returns the backing ThreadLocal object)
 - * is used solely by InheritableThreadLocal, so that the
 - * bequeath method can invoke the relevant childValue method. Arguably
 - * this inner class belongs in InheritableThreadLocal, but putting it
 - * there would complicate implementation.
 - */
 - class SecureKey{
 - ThreadLocal threadLocal() {
 - return ThreadLocal.this;
 - }
 - }
 - }