1. /*
  2. * @(#)ThreadLocal.java 1.16 00/02/02
  3. *
  4. * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved.
  5. *
  6. * This software is the proprietary information of Sun Microsystems, Inc.
  7. * Use is subject to license terms.
  8. *
  9. */
  10. package java.lang;
  11. import java.util.*;
  12. /**
  13. * This class provides ThreadLocal variables. These variables differ from
  14. * their normal counterparts in that each thread that accesses one (via its
  15. * get or set method) has its own, independently initialized copy of the
  16. * variable. ThreadLocal objects are typically private static variables in
  17. * classes that wish to associate state with a thread (e.g., a user ID or
  18. * Transaction ID).
  19. *
  20. * <p>Each thread holds an implicit reference to its copy of a ThreadLocal
  21. * as long as the thread is alive and the ThreadLocal object is accessible;
  22. * after a thread goes away, all of its copies of ThreadLocal variables are
  23. * subject to garbage collection (unless other references to these copies
  24. * exist).
  25. *
  26. * @author Josh Bloch
  27. * @version 1.16, 02/02/00
  28. * @since 1.2
  29. */
  30. public class ThreadLocal {
  31. /**
  32. * Initial capacity of per-thread HashMap from ThreadLocal to value.
  33. * The size should be approximately twice the the number of thread local
  34. * variables that thread might have.
  35. */
  36. private static final int INITIAL_CAPACITY = 11;
  37. /**
  38. * Creates a ThreadLocal variable.
  39. */
  40. public ThreadLocal() {
  41. key = new SecureKey();
  42. }
  43. /**
  44. * Secure key representing this thread local variable. This key is used
  45. * in preference to the ThreadLocal object itself, to map this variable to
  46. * its per-thread value, to prevent an attacker from overriding the equals
  47. * method to spoof another ThreadLocal and steal its value.
  48. */
  49. Object key;
  50. /**
  51. * Returns the calling thread's initial value for this ThreadLocal
  52. * variable. This method will be called once per accessing thread for
  53. * each ThreadLocal, the first time each thread accesses the variable
  54. * with get or set. If the programmer desires ThreadLocal variables
  55. * to be initialized to some value other than null, ThreadLocal must
  56. * be subclassed, and this method overridden. Typically, an anonymous
  57. * inner class will be used. Typical implementations of initialValue
  58. * will call an appropriate constructor and return the newly constructed
  59. * object.
  60. *
  61. * @return the initial value for this ThreadLocal
  62. */
  63. protected Object initialValue() {
  64. return null;
  65. }
  66. /**
  67. * Returns the value in the calling thread's copy of this ThreadLocal
  68. * variable. Creates and initializes the copy if this is the first time
  69. * the thread has called this method.
  70. *
  71. * @return the value of this ThreadLocal
  72. */
  73. public Object get() {
  74. Thread ourThread = Thread.currentThread();
  75. Map map = ourThread.threadLocals;
  76. Object value = map.get(key);
  77. if (value==null && !map.containsKey(key)) {
  78. if (map == Collections.EMPTY_MAP)
  79. map = ourThread.threadLocals = new HashMap(INITIAL_CAPACITY);
  80. value = initialValue();
  81. map.put(key, value);
  82. }
  83. return value;
  84. }
  85. /**
  86. * Sets the calling thread's instance of this ThreadLocal variable
  87. * to the given value. This is only used to change the value from
  88. * the one assigned by the initialValue method, and many applications
  89. * will have no need for this functionality.
  90. *
  91. * @param value the value to be stored in the calling threads' copy of
  92. * this ThreadLocal.
  93. */
  94. public void set(Object value) {
  95. Thread ourThread = Thread.currentThread();
  96. Map map = ourThread.threadLocals;
  97. if (map == Collections.EMPTY_MAP)
  98. map = ourThread.threadLocals = new HashMap(INITIAL_CAPACITY);
  99. map.put(key, value);
  100. }
  101. /**
  102. * An object of this class is used in place of the ThreadLocal itself
  103. * as a key in the per-Thread ThreadLocal->value Map. This prevents
  104. * a "spoof attack" where one ThreadLocal pretends to be another
  105. * by overriding the equals (and hashCode) method and returning true
  106. * when it should return false.
  107. *
  108. * The sole method (which returns the backing ThreadLocal object)
  109. * is used solely by InheritableThreadLocal, so that the
  110. * bequeath method can invoke the relevant childValue method. Arguably
  111. * this inner class belongs in InheritableThreadLocal, but putting it
  112. * there would complicate implementation.
  113. */
  114. class SecureKey{
  115. ThreadLocal threadLocal() {
  116. return ThreadLocal.this;
  117. }
  118. }
  119. }