1. /*
  2. * @(#)ThreadLocal.java 1.10 02/04/18
  3. *
  4. * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.lang;
  8. import java.lang.ref.*;
  9. /**
  10. * This class provides ThreadLocal variables. These variables differ from
  11. * their normal counterparts in that each thread that accesses one (via its
  12. * get or set method) has its own, independently initialized copy of the
  13. * variable. ThreadLocal objects are typically private static variables in
  14. * classes that wish to associate state with a thread (e.g., a user ID or
  15. * Transaction ID).
  16. * <p>
  17. * Each thread holds an implicit reference to its copy of a ThreadLocal
  18. * as long as the thread is alive and the ThreadLocal object is accessible;
  19. * after a thread goes away, all of its copies of ThreadLocal variables are
  20. * subject to garbage collection (unless other references to these copies
  21. * exist).
  22. *
  23. * @author Josh Bloch and Doug Lea
  24. * @version 1.10 04/18/02
  25. * @since JDK1.2
  26. */
  27. public class ThreadLocal {
  28. /**
  29. * ThreadLocals rely on per-thread hash maps attached to each thread
  30. * (Thread.threadLocals and inheritableThreadLocals). The ThreadLocal
  31. * objects act as keys, searched via threadLocalHashCode. This is a
  32. * custom hash code (useful only within ThreadLocalMaps) that eliminates
  33. * collisions in the common case where consecutively constructed
  34. * ThreadLocals are used by the same threads, while remaining well-behaved
  35. * in less common cases.
  36. */
  37. private final int threadLocalHashCode = nextHashCode();
  38. /**
  39. * The next hash code to be given out. Accessed only by like-named method.
  40. */
  41. private static int nextHashCode = 0;
  42. /**
  43. * The difference between successively generated hash codes - turns
  44. * implicit sequential thread-local IDs into near-optimally spread
  45. * multiplicative hash values for power-of-two-sized tables.
  46. */
  47. private static final int HASH_INCREMENT = 0x61c88647;
  48. /**
  49. * Compute the next hash code. The static synchronization used here
  50. * should not be a performance bottleneck. When ThreadLocals are
  51. * generated in different threads at a fast enough rate to regularly
  52. * contend on this lock, memory contention is by far a more serious
  53. * problem than lock contention.
  54. */
  55. private static synchronized int nextHashCode() {
  56. int h = nextHashCode;
  57. nextHashCode = h + HASH_INCREMENT;
  58. return h;
  59. }
  60. /**
  61. * Creates a ThreadLocal variable.
  62. */
  63. public ThreadLocal() {
  64. }
  65. /**
  66. * Returns the calling thread's initial value for this ThreadLocal
  67. * variable. This method will be called once per accessing thread for
  68. * each ThreadLocal, the first time each thread accesses the variable
  69. * with get or set. If the programmer desires ThreadLocal variables
  70. * to be initialized to some value other than null, ThreadLocal must
  71. * be subclassed, and this method overridden. Typically, an anonymous
  72. * inner class will be used. Typical implementations of initialValue
  73. * will call an appropriate constructor and return the newly constructed
  74. * object.
  75. */
  76. protected Object initialValue() {
  77. return null;
  78. }
  79. /**
  80. * Returns the value in the calling thread's copy of this ThreadLocal
  81. * variable. Creates and initializes the copy if this is the first time
  82. * the thread has called this method.
  83. *
  84. * @return the current thread's value of this threadLocal
  85. */
  86. public Object get() {
  87. Thread t = Thread.currentThread();
  88. ThreadLocalMap map = getMap(t);
  89. if (map != null)
  90. return map.get(this);
  91. // Maps are constructed lazily. if the map for this thread
  92. // doesn't exist, create it, with this ThreadLocal and its
  93. // initial value as its only entry.
  94. Object value = initialValue();
  95. createMap(t, value);
  96. return value;
  97. }
  98. /**
  99. * Sets the calling thread's instance of this ThreadLocal variable
  100. * to the given value. This is only used to change the value from
  101. * the one assigned by the initialValue method, and many applications
  102. * will have no need for this functionality.
  103. *
  104. * @param value the value to be stored in the calling threads' copy of
  105. * this ThreadLocal.
  106. */
  107. public void set(Object value) {
  108. Thread t = Thread.currentThread();
  109. ThreadLocalMap map = getMap(t);
  110. if (map != null)
  111. map.set(this, value);
  112. else
  113. createMap(t, value);
  114. }
  115. /**
  116. * Get the map associated with a ThreadLocal. Overridden in
  117. * InheritableThreadLocal.
  118. *
  119. * @param t the current thread
  120. * @return the map
  121. */
  122. ThreadLocalMap getMap(Thread t) {
  123. return t.threadLocals;
  124. }
  125. /**
  126. * Create the map associated with a ThreadLocal. Overridden in
  127. * InheritableThreadLocal.
  128. *
  129. * @param t the current thread
  130. * @param firstValue value for the initial entry of the map
  131. * @param map the map to store.
  132. */
  133. void createMap(Thread t, Object firstValue) {
  134. t.threadLocals = new ThreadLocalMap(this, firstValue);
  135. }
  136. /**
  137. * Factory method to create map of inherited thread locals.
  138. * Designed to be called only from Thread constructor.
  139. *
  140. * @param parentMap the map associated with parent thread
  141. * @return a map containing the parent's inheritable bindings
  142. */
  143. static ThreadLocalMap createInheritedMap(ThreadLocalMap parentMap) {
  144. return new ThreadLocalMap(parentMap);
  145. }
  146. /**
  147. * Method childValue is visibly defined in subclass
  148. * InheritableThreadLocal, but is internally defined here for the
  149. * sake of providing createInheritedMap factory method without
  150. * needing to subclass the map class in InheritableThreadLocal.
  151. * This technique is preferable to the alternative of embedding
  152. * instanceof tests in methods.
  153. */
  154. Object childValue(Object parentValue) {
  155. throw new UnsupportedOperationException();
  156. }
  157. /**
  158. * ThreadLocalMap is a customized hash map suitable only for
  159. * maintaining thread local values. No operations are exported
  160. * outside of the ThreadLocal class. The class is package private to
  161. * allow declaration of fields in class Thread. To help deal with
  162. * very large and long-lived usages, the hash table entries use
  163. * WeakReferences for keys. However, since reference queues are not
  164. * used, stale entries are guaranteed to be removed only when
  165. * the table starts running out of space.
  166. */
  167. static class ThreadLocalMap {
  168. /**
  169. * The entries in this hash map extend WeakReference, using
  170. * its main ref field as the key (which is always a
  171. * ThreadLocal object). Note that null keys (i.e. entry.get()
  172. * == null) mean that the key is no longer referenced, so the
  173. * entry can be expunged from table. Such entries are referred to
  174. * as "stale entries" in the code that follows.
  175. */
  176. private static class Entry extends WeakReference {
  177. /** The value associated with this ThreadLocal. */
  178. private Object value;
  179. private Entry(ThreadLocal k, Object v) {
  180. super(k);
  181. value = v;
  182. }
  183. }
  184. /**
  185. * The initial capacity -- MUST be a power of two.
  186. */
  187. private static final int INITIAL_CAPACITY = 16;
  188. /**
  189. * The table, resized as necessary.
  190. * table.length MUST always be a power of two.
  191. */
  192. private Entry[] table;
  193. /**
  194. * The number of entries in the table.
  195. */
  196. private int size = 0;
  197. /**
  198. * The next size value at which to resize.
  199. */
  200. private int threshold;
  201. /**
  202. * Set the resize threshold to maintain at worst a 2/3 load factor.
  203. */
  204. private void setThreshold(int len) {
  205. threshold = len * 2 / 3;
  206. }
  207. /**
  208. * Increment i modulo len.
  209. */
  210. private static int nextIndex(int i, int len) {
  211. return ((i + 1 < len) ? i + 1 : 0);
  212. }
  213. /**
  214. * Decrement i modulo len.
  215. */
  216. private static int prevIndex(int i, int len) {
  217. return ((i - 1 >= 0) ? i - 1 : len - 1);
  218. }
  219. /**
  220. * Construct a new map initially containing (firstKey, firstValue).
  221. * ThreadLocalMaps are constructed lazily, so we only create
  222. * one when we have at least one entry to put in it.
  223. */
  224. ThreadLocalMap(ThreadLocal firstKey, Object firstValue) {
  225. table = new Entry[INITIAL_CAPACITY];
  226. int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY - 1);
  227. table[i] = new Entry(firstKey, firstValue);
  228. size = 1;
  229. setThreshold(INITIAL_CAPACITY);
  230. }
  231. /**
  232. * Construct a new map including all Inheritable ThreadLocals
  233. * from given parent map. Called only by createInheritedMap.
  234. *
  235. * @param parentMap the map associated with parent thread.
  236. */
  237. private ThreadLocalMap(ThreadLocalMap parentMap) {
  238. Entry[] parentTable = parentMap.table;
  239. int len = parentTable.length;
  240. setThreshold(len);
  241. table = new Entry[len];
  242. for (int j = 0; j < len; j++) {
  243. Entry e = parentTable[j];
  244. if (e != null) {
  245. Object k = e.get();
  246. if (k != null) {
  247. ThreadLocal key = (ThreadLocal)(k);
  248. Object value = key.childValue(e.value);
  249. Entry c = new Entry(key, value);
  250. int h = key.threadLocalHashCode & (len - 1);
  251. while (table[h] != null)
  252. h = nextIndex(h, len);
  253. table[h] = c;
  254. size++;
  255. }
  256. }
  257. }
  258. }
  259. /**
  260. * Get the value associated with key with code h. This method itself
  261. * handles only the fast path: a direct hit of existing key. It
  262. * otherwise relays to getAfterMiss. This is designed to maximize
  263. * performance for direct hits, in part by making this method readily
  264. * inlinable.
  265. *
  266. * @param key the thread local object
  267. * @param h key's hash code
  268. * @return the value associated with key
  269. */
  270. private Object get(ThreadLocal key) {
  271. int i = key.threadLocalHashCode & (table.length - 1);
  272. Entry e = table[i];
  273. if (e != null && e.get() == key)
  274. return e.value;
  275. return getAfterMiss(key, i, e);
  276. }
  277. /**
  278. * Version of get method for use when key is not found in its
  279. * direct hash slot.
  280. *
  281. * @param key the thread local object
  282. * @param i the table index for key's hash code
  283. * @param e the entry at table[i];
  284. * @return the value associated with key
  285. */
  286. private Object getAfterMiss(ThreadLocal key, int i, Entry e) {
  287. Entry[] tab = table;
  288. int len = tab.length;
  289. while (e != null) {
  290. Object k = e.get();
  291. if (k == key)
  292. return e.value;
  293. if (k == null)
  294. return replaceStaleEntry(key, null, i, true);
  295. i = nextIndex(i, len);
  296. e = tab[i];
  297. }
  298. Object value = key.initialValue();
  299. tab[i] = new Entry(key, value);
  300. if (++size >= threshold)
  301. rehash();
  302. return value;
  303. }
  304. /**
  305. * Set the value associated with key.
  306. *
  307. * @param key the thread local object
  308. * @param value the value to be set
  309. */
  310. private void set(ThreadLocal key, Object value) {
  311. // We don't use a fast path as with get() because it is at
  312. // least as common to use set() to create new entries as
  313. // it is to replace existing ones, in which case, a fast
  314. // path would fail more often than not.
  315. Entry[] tab = table;
  316. int len = tab.length;
  317. int i = key.threadLocalHashCode & (len-1);
  318. for (Entry e = tab[i]; e != null; e = tab[i = nextIndex(i, len)]) {
  319. Object k = e.get();
  320. if (k == key) {
  321. e.value = value;
  322. return;
  323. }
  324. if (k == null) {
  325. replaceStaleEntry(key, value, i, false);
  326. return;
  327. }
  328. }
  329. tab[i] = new Entry(key, value);
  330. if (++size >= threshold)
  331. rehash();
  332. }
  333. /**
  334. * Remove the entry for key.
  335. THIS IS USED ONLY BY ThreadLocal.remove, WHICH IS NOT CURRENTLY
  336. PART OF THE PUBLIC API. IF IT IS ADDED TO THE PUBLIC API AT SOME
  337. POINT, THIS METHOD MUST BE UNCOMMENTED.
  338. private void remove(ThreadLocal key) {
  339. Entry[] tab = table;
  340. int len = tab.length;
  341. int i = key.threadLocalHashCode & (len-1);
  342. for (Entry e = tab[i]; e != null; e = tab[i = nextIndex(i, len)]) {
  343. if (e.get() == key) {
  344. e.clear();
  345. expungeStaleEntry(i);
  346. return;
  347. }
  348. }
  349. }
  350. */
  351. /**
  352. * Replace a stale entry encountered during a get or set operation
  353. * with an entry for the specified key. If actAsGet is true and an
  354. * entry for the key already exists, the value in the entry is
  355. * unchanged; if no entry exists for the key, the value in the new
  356. * entry is obtained by calling key.initialValue. If actAsGet is
  357. * false, the value passed in the value parameter is stored in the
  358. * entry, whether or not an entry already exists for the specified key.
  359. *
  360. * As a side effect, this method expunges all stale entries in the
  361. * "run" containing the stale entry. (A run is a sequence of entries
  362. * between two null slots.)
  363. *
  364. * @param key the key
  365. * @param value the value to be associated with key; meaningful only
  366. * if actAsGet is false.
  367. * @param staleSlot index of the first stale entry encountered while
  368. * searching for key.
  369. * @param actAsGet true if this method should act as a get; false
  370. * it should act as a set.
  371. * @return the value associated with key after the operation completes.
  372. */
  373. private Object replaceStaleEntry(ThreadLocal key, Object value,
  374. int staleSlot, boolean actAsGet) {
  375. Entry[] tab = table;
  376. int len = tab.length;
  377. Entry e;
  378. // Back up to check for prior stale entry in current run.
  379. // We clean out whole runs at a time to avoid continual
  380. // incremental rehashing due to garbage collector freeing
  381. // up refs in bunches (i.e., whenever the collector runs).
  382. int slotToExpunge = staleSlot;
  383. for (int i = prevIndex(staleSlot, len); (e = tab[i]) != null;
  384. i = prevIndex(i, len))
  385. if (e.get() == null)
  386. slotToExpunge = i;
  387. // Find either the key or trailing null slot of run, whichever
  388. // occurs first
  389. for (int i = nextIndex(staleSlot, len); (e = tab[i]) != null;
  390. i = nextIndex(i, len)) {
  391. Object k = e.get();
  392. // If we find key, then we need to swap it
  393. // with the stale entry to maintain hash table order.
  394. // The newly stale slot, or any other stale slot
  395. // encountered above it, can then be sent to expungeStaleEntry
  396. // to remove or rehash all of the other entries in run.
  397. if (k == key) {
  398. if (actAsGet)
  399. value = e.value;
  400. else
  401. e.value = value;
  402. tab[i] = tab[staleSlot];
  403. tab[staleSlot] = e;
  404. // Start expunge at preceding stale entry if it exists
  405. if (slotToExpunge == staleSlot)
  406. slotToExpunge = i;
  407. expungeStaleEntry(slotToExpunge);
  408. return value;
  409. }
  410. // If we didn't find stale entry on backward scan, the
  411. // the first stale entry seen while scanning for key is the
  412. // first still present in the run.
  413. if (k == null && slotToExpunge == staleSlot)
  414. slotToExpunge = i;
  415. }
  416. // If key not found, put new entry in stale slot
  417. if (actAsGet)
  418. value = key.initialValue();
  419. tab[staleSlot].value = null; // Help the GC
  420. tab[staleSlot] = new Entry(key, value);
  421. // If there are any other stale entries in run, expunge them
  422. if (slotToExpunge != staleSlot)
  423. expungeStaleEntry(slotToExpunge);
  424. return value;
  425. }
  426. /**
  427. * Expunge a stale entry by rehashing any possibly colliding entries
  428. * lying between staleSlot and the next null slot. This also expunges
  429. * any other stale entries encountered before the trailing null. See
  430. * Knuth, Section 6.4
  431. *
  432. * @param staleSlot index of slot known to have null key
  433. */
  434. private void expungeStaleEntry(int staleSlot) {
  435. Entry[] tab = table;
  436. int len = tab.length;
  437. // expunge entry at staleSlot
  438. tab[staleSlot].value = null; // Help the GC
  439. tab[staleSlot] = null;
  440. size--;
  441. // Rehash until we encounter null
  442. Entry e;
  443. for (int i = nextIndex(staleSlot, len); (e = tab[i]) != null;
  444. i = nextIndex(i, len)) {
  445. Object k = e.get();
  446. if (k == null) {
  447. e.value = null; // Help the GC
  448. tab[i] = null;
  449. size--;
  450. } else {
  451. ThreadLocal key = (ThreadLocal)(k);
  452. int h = key.threadLocalHashCode & (len - 1);
  453. if (h != i) {
  454. tab[i] = null;
  455. // Unlike Knuth 6.4 Algorithm R, we must scan until
  456. // null because multiple entries could have been stale.
  457. while (tab[h] != null)
  458. h = nextIndex(h, len);
  459. tab[h] = e;
  460. }
  461. }
  462. }
  463. }
  464. /**
  465. * Re-pack and/or re-size the table. First scan the entire
  466. * table removing stale entries. If this doesn't sufficiently
  467. * shrink the size of the table, double the table size.
  468. */
  469. private void rehash() {
  470. expungeStaleEntries();
  471. // Use lower threshold for doubling to avoid hysteresis
  472. if (size >= threshold - threshold / 4)
  473. resize();
  474. }
  475. /**
  476. * Double the capacity of the table.
  477. */
  478. private void resize() {
  479. Entry[] oldTab = table;
  480. int oldLen = oldTab.length;
  481. int newLen = oldLen * 2;
  482. Entry[] newTab = new Entry[newLen];
  483. int count = 0;
  484. for (int j = 0; j < oldLen; ++j) {
  485. Entry e = oldTab[j];
  486. oldTab[j] = null; // Help the GC
  487. if (e != null) {
  488. Object k = e.get();
  489. if (k == null) {
  490. e.value = null; // Help the GC
  491. } else {
  492. ThreadLocal key = (ThreadLocal)(k);
  493. int h = key.threadLocalHashCode & (newLen - 1);
  494. while (newTab[h] != null)
  495. h = nextIndex(h, newLen);
  496. newTab[h] = e;
  497. count++;
  498. }
  499. }
  500. }
  501. setThreshold(newLen);
  502. size = count;
  503. table = newTab;
  504. }
  505. /**
  506. * Expunge all stale entries in the table.
  507. */
  508. private void expungeStaleEntries() {
  509. Entry[] tab = table;
  510. int len = tab.length;
  511. for (int j = 0; j < len; j++) {
  512. Entry e = tab[j];
  513. if (e != null && e.get() == null)
  514. expungeStaleEntry(j);
  515. }
  516. }
  517. }
  518. }