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.concurrent.atomic.AtomicInteger;
29
30 /**
31 * This class provides thread-local variables. These variables differ from
32 * their normal counterparts in that each thread that accesses one (via its
33 * <tt>get</tt> or <tt>set</tt> method) has its own, independently initialized
34 * copy of the variable. <tt>ThreadLocal</tt> instances are typically private
35 * static fields in classes that wish to associate state with a thread (e.g.,
36 * a user ID or Transaction ID).
37 *
38 * <p>For example, the class below generates unique identifiers local to each
39 * thread.
40 * A thread's id is assigned the first time it invokes <tt>ThreadId.get()</tt>
41 * and remains unchanged on subsequent calls.
42 * <pre>
43 * import java.util.concurrent.atomic.AtomicInteger;
44 *
45 * public class ThreadId {
46 * // Atomic integer containing the next thread ID to be assigned
47 * private static final AtomicInteger nextId = new AtomicInteger(0);
48 *
49 * // Thread local variable containing each thread's ID
50 * private static final ThreadLocal<Integer> threadId =
51 * new ThreadLocal<Integer>() {
52 * @Override protected Integer initialValue() {
53 * return nextId.getAndIncrement();
54 * }
55 * };
56 *
57 * // Returns the current thread's unique ID, assigning it if necessary
58 * public static int get() {
59 * return threadId.get();
60 * }
61 * }
62 * </pre>
63 * <p>Each thread holds an implicit reference to its copy of a thread-local
64 * variable as long as the thread is alive and the <tt>ThreadLocal</tt>
65 * instance is accessible; after a thread goes away, all of its copies of
66 * thread-local instances are subject to garbage collection (unless other
67 * references to these copies exist).
68 *
69 * @author Josh Bloch and Doug Lea
70 * @since 1.2
71 */
72 public class ThreadLocal<T> {
73 /**
74 * ThreadLocals rely on per-thread linear-probe hash maps attached
75 * to each thread (Thread.threadLocals and
76 * inheritableThreadLocals). The ThreadLocal objects act as keys,
77 * searched via threadLocalHashCode. This is a custom hash code
78 * (useful only within ThreadLocalMaps) that eliminates collisions
79 * in the common case where consecutively constructed ThreadLocals
80 * are used by the same threads, while remaining well-behaved in
81 * less common cases.
82 */
83 private final int threadLocalHashCode = nextHashCode();
84
91
92 /**
93 * The difference between successively generated hash codes - turns
94 * implicit sequential thread-local IDs into near-optimally spread
95 * multiplicative hash values for power-of-two-sized tables.
96 */
97 private static final int HASH_INCREMENT = 0x61c88647;
98
99 /**
100 * Returns the next hash code.
101 */
102 private static int nextHashCode() {
103 return nextHashCode.getAndAdd(HASH_INCREMENT);
104 }
105
106 /**
107 * Returns the current thread's "initial value" for this
108 * thread-local variable. This method will be invoked the first
109 * time a thread accesses the variable with the {@link #get}
110 * method, unless the thread previously invoked the {@link #set}
111 * method, in which case the <tt>initialValue</tt> method will not
112 * be invoked for the thread. Normally, this method is invoked at
113 * most once per thread, but it may be invoked again in case of
114 * subsequent invocations of {@link #remove} followed by {@link #get}.
115 *
116 * <p>This implementation simply returns <tt>null</tt>; if the
117 * programmer desires thread-local variables to have an initial
118 * value other than <tt>null</tt>, <tt>ThreadLocal</tt> must be
119 * subclassed, and this method overridden. Typically, an
120 * anonymous inner class will be used.
121 *
122 * @return the initial value for this thread-local
123 */
124 protected T initialValue() {
125 return null;
126 }
127
128 /**
129 * Creates a thread local variable.
130 */
131 public ThreadLocal() {
132 }
133
134 /**
135 * Returns the value in the current thread's copy of this
136 * thread-local variable. If the variable has no value for the
137 * current thread, it is first initialized to the value returned
138 * by an invocation of the {@link #initialValue} method.
139 *
140 * @return the current thread's value of this thread-local
141 */
142 public T get() {
143 Thread t = Thread.currentThread();
144 ThreadLocalMap map = getMap(t);
145 if (map != null) {
146 ThreadLocalMap.Entry e = map.getEntry(this);
147 if (e != null) {
148 @SuppressWarnings("unchecked")
149 T result = (T)e.value;
178 *
179 * @param value the value to be stored in the current thread's copy of
180 * this thread-local.
181 */
182 public void set(T value) {
183 Thread t = Thread.currentThread();
184 ThreadLocalMap map = getMap(t);
185 if (map != null)
186 map.set(this, value);
187 else
188 createMap(t, value);
189 }
190
191 /**
192 * Removes the current thread's value for this thread-local
193 * variable. If this thread-local variable is subsequently
194 * {@linkplain #get read} by the current thread, its value will be
195 * reinitialized by invoking its {@link #initialValue} method,
196 * unless its value is {@linkplain #set set} by the current thread
197 * in the interim. This may result in multiple invocations of the
198 * <tt>initialValue</tt> method in the current thread.
199 *
200 * @since 1.5
201 */
202 public void remove() {
203 ThreadLocalMap m = getMap(Thread.currentThread());
204 if (m != null)
205 m.remove(this);
206 }
207
208 /**
209 * Get the map associated with a ThreadLocal. Overridden in
210 * InheritableThreadLocal.
211 *
212 * @param t the current thread
213 * @return the map
214 */
215 ThreadLocalMap getMap(Thread t) {
216 return t.threadLocals;
217 }
218
234 * @param parentMap the map associated with parent thread
235 * @return a map containing the parent's inheritable bindings
236 */
237 static ThreadLocalMap createInheritedMap(ThreadLocalMap parentMap) {
238 return new ThreadLocalMap(parentMap);
239 }
240
241 /**
242 * Method childValue is visibly defined in subclass
243 * InheritableThreadLocal, but is internally defined here for the
244 * sake of providing createInheritedMap factory method without
245 * needing to subclass the map class in InheritableThreadLocal.
246 * This technique is preferable to the alternative of embedding
247 * instanceof tests in methods.
248 */
249 T childValue(T parentValue) {
250 throw new UnsupportedOperationException();
251 }
252
253 /**
254 * ThreadLocalMap is a customized hash map suitable only for
255 * maintaining thread local values. No operations are exported
256 * outside of the ThreadLocal class. The class is package private to
257 * allow declaration of fields in class Thread. To help deal with
258 * very large and long-lived usages, the hash table entries use
259 * WeakReferences for keys. However, since reference queues are not
260 * used, stale entries are guaranteed to be removed only when
261 * the table starts running out of space.
262 */
263 static class ThreadLocalMap {
264
265 /**
266 * The entries in this hash map extend WeakReference, using
267 * its main ref field as the key (which is always a
268 * ThreadLocal object). Note that null keys (i.e. entry.get()
269 * == null) mean that the key is no longer referenced, so the
270 * entry can be expunged from table. Such entries are referred to
271 * as "stale entries" in the code that follows.
272 */
273 static class Entry extends WeakReference<ThreadLocal<?>> {
582 h = nextIndex(h, len);
583 tab[h] = e;
584 }
585 }
586 }
587 return i;
588 }
589
590 /**
591 * Heuristically scan some cells looking for stale entries.
592 * This is invoked when either a new element is added, or
593 * another stale one has been expunged. It performs a
594 * logarithmic number of scans, as a balance between no
595 * scanning (fast but retains garbage) and a number of scans
596 * proportional to number of elements, that would find all
597 * garbage but would cause some insertions to take O(n) time.
598 *
599 * @param i a position known NOT to hold a stale entry. The
600 * scan starts at the element after i.
601 *
602 * @param n scan control: <tt>log2(n)</tt> cells are scanned,
603 * unless a stale entry is found, in which case
604 * <tt>log2(table.length)-1</tt> additional cells are scanned.
605 * When called from insertions, this parameter is the number
606 * of elements, but when from replaceStaleEntry, it is the
607 * table length. (Note: all this could be changed to be either
608 * more or less aggressive by weighting n instead of just
609 * using straight log n. But this version is simple, fast, and
610 * seems to work well.)
611 *
612 * @return true if any stale entries have been removed.
613 */
614 private boolean cleanSomeSlots(int i, int n) {
615 boolean removed = false;
616 Entry[] tab = table;
617 int len = tab.length;
618 do {
619 i = nextIndex(i, len);
620 Entry e = tab[i];
621 if (e != null && e.get() == null) {
622 n = len;
623 removed = true;
624 i = expungeStaleEntry(i);
|
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 *
47 * public class ThreadId {
48 * // Atomic integer containing the next thread ID to be assigned
49 * private static final AtomicInteger nextId = new AtomicInteger(0);
50 *
51 * // Thread local variable containing each thread's ID
52 * private static final ThreadLocal<Integer> threadId =
53 * new ThreadLocal<Integer>() {
54 * @Override protected Integer initialValue() {
55 * return nextId.getAndIncrement();
56 * }
57 * };
58 *
59 * // Returns the current thread's unique ID, assigning it if necessary
60 * public static int get() {
61 * return threadId.get();
62 * }
63 * }
64 * </pre>
65 * <p>Each thread holds an implicit reference to its copy of a thread-local
66 * variable as long as the thread is alive and the {@code ThreadLocal}
67 * instance is accessible; after a thread goes away, all of its copies of
68 * thread-local instances are subject to garbage collection (unless other
69 * references to these copies exist).
70 *
71 * @author Josh Bloch and Doug Lea
72 * @since 1.2
73 */
74 public class ThreadLocal<T> {
75 /**
76 * ThreadLocals rely on per-thread linear-probe hash maps attached
77 * to each thread (Thread.threadLocals and
78 * inheritableThreadLocals). The ThreadLocal objects act as keys,
79 * searched via threadLocalHashCode. This is a custom hash code
80 * (useful only within ThreadLocalMaps) that eliminates collisions
81 * in the common case where consecutively constructed ThreadLocals
82 * are used by the same threads, while remaining well-behaved in
83 * less common cases.
84 */
85 private final int threadLocalHashCode = nextHashCode();
86
93
94 /**
95 * The difference between successively generated hash codes - turns
96 * implicit sequential thread-local IDs into near-optimally spread
97 * multiplicative hash values for power-of-two-sized tables.
98 */
99 private static final int HASH_INCREMENT = 0x61c88647;
100
101 /**
102 * Returns the next hash code.
103 */
104 private static int nextHashCode() {
105 return nextHashCode.getAndAdd(HASH_INCREMENT);
106 }
107
108 /**
109 * Returns the current thread's "initial value" for this
110 * thread-local variable. This method will be invoked the first
111 * time a thread accesses the variable with the {@link #get}
112 * method, unless the thread previously invoked the {@link #set}
113 * method, in which case the {@code initialValue} method will not
114 * be invoked for the thread. Normally, this method is invoked at
115 * most once per thread, but it may be invoked again in case of
116 * subsequent invocations of {@link #remove} followed by {@link #get}.
117 *
118 * <p>This implementation simply returns {@code null}; if the
119 * programmer desires thread-local variables to have an initial
120 * value other than {@code null}, {@code ThreadLocal} must be
121 * subclassed, and this method overridden. Typically, an
122 * anonymous inner class will be used.
123 *
124 * @return the initial value for this thread-local
125 */
126 protected T initialValue() {
127 return null;
128 }
129
130 /**
131 * Creates a thread local variable. The initial value of the variable is
132 * determined by invoking the {@code get} method on the {@code Supplier}.
133 *
134 * @param supplier the supplier to be used to determine the initial value
135 * @return a new thread local variable
136 * @since 1.8
137 */
138 public static <T> ThreadLocal<T> withInitial(Supplier<? extends T> supplier) {
139 return new SuppliedThreadLocal<>(supplier);
140 }
141
142 /**
143 * Creates a thread local variable.
144 * @see #withInitial(java.util.function.Supplier)
145 */
146 public ThreadLocal() {
147 }
148
149 /**
150 * Returns the value in the current thread's copy of this
151 * thread-local variable. If the variable has no value for the
152 * current thread, it is first initialized to the value returned
153 * by an invocation of the {@link #initialValue} method.
154 *
155 * @return the current thread's value of this thread-local
156 */
157 public T get() {
158 Thread t = Thread.currentThread();
159 ThreadLocalMap map = getMap(t);
160 if (map != null) {
161 ThreadLocalMap.Entry e = map.getEntry(this);
162 if (e != null) {
163 @SuppressWarnings("unchecked")
164 T result = (T)e.value;
193 *
194 * @param value the value to be stored in the current thread's copy of
195 * this thread-local.
196 */
197 public void set(T value) {
198 Thread t = Thread.currentThread();
199 ThreadLocalMap map = getMap(t);
200 if (map != null)
201 map.set(this, value);
202 else
203 createMap(t, value);
204 }
205
206 /**
207 * Removes the current thread's value for this thread-local
208 * variable. If this thread-local variable is subsequently
209 * {@linkplain #get read} by the current thread, its value will be
210 * reinitialized by invoking its {@link #initialValue} method,
211 * unless its value is {@linkplain #set set} by the current thread
212 * in the interim. This may result in multiple invocations of the
213 * {@code initialValue} method in the current thread.
214 *
215 * @since 1.5
216 */
217 public void remove() {
218 ThreadLocalMap m = getMap(Thread.currentThread());
219 if (m != null)
220 m.remove(this);
221 }
222
223 /**
224 * Get the map associated with a ThreadLocal. Overridden in
225 * InheritableThreadLocal.
226 *
227 * @param t the current thread
228 * @return the map
229 */
230 ThreadLocalMap getMap(Thread t) {
231 return t.threadLocals;
232 }
233
249 * @param parentMap the map associated with parent thread
250 * @return a map containing the parent's inheritable bindings
251 */
252 static ThreadLocalMap createInheritedMap(ThreadLocalMap parentMap) {
253 return new ThreadLocalMap(parentMap);
254 }
255
256 /**
257 * Method childValue is visibly defined in subclass
258 * InheritableThreadLocal, but is internally defined here for the
259 * sake of providing createInheritedMap factory method without
260 * needing to subclass the map class in InheritableThreadLocal.
261 * This technique is preferable to the alternative of embedding
262 * instanceof tests in methods.
263 */
264 T childValue(T parentValue) {
265 throw new UnsupportedOperationException();
266 }
267
268 /**
269 * An extension of ThreadLocal that obtains its initial value from
270 * the specified {@code Supplier}.
271 */
272 static final class SuppliedThreadLocal<T> extends ThreadLocal<T> {
273
274 private final Supplier<? extends T> supplier;
275
276 SuppliedThreadLocal(Supplier<? extends T> supplier) {
277 this.supplier = Objects.requireNonNull(supplier);
278 }
279
280 @Override
281 protected T initialValue() {
282 return supplier.get();
283 }
284 }
285
286 /**
287 * ThreadLocalMap is a customized hash map suitable only for
288 * maintaining thread local values. No operations are exported
289 * outside of the ThreadLocal class. The class is package private to
290 * allow declaration of fields in class Thread. To help deal with
291 * very large and long-lived usages, the hash table entries use
292 * WeakReferences for keys. However, since reference queues are not
293 * used, stale entries are guaranteed to be removed only when
294 * the table starts running out of space.
295 */
296 static class ThreadLocalMap {
297
298 /**
299 * The entries in this hash map extend WeakReference, using
300 * its main ref field as the key (which is always a
301 * ThreadLocal object). Note that null keys (i.e. entry.get()
302 * == null) mean that the key is no longer referenced, so the
303 * entry can be expunged from table. Such entries are referred to
304 * as "stale entries" in the code that follows.
305 */
306 static class Entry extends WeakReference<ThreadLocal<?>> {
615 h = nextIndex(h, len);
616 tab[h] = e;
617 }
618 }
619 }
620 return i;
621 }
622
623 /**
624 * Heuristically scan some cells looking for stale entries.
625 * This is invoked when either a new element is added, or
626 * another stale one has been expunged. It performs a
627 * logarithmic number of scans, as a balance between no
628 * scanning (fast but retains garbage) and a number of scans
629 * proportional to number of elements, that would find all
630 * garbage but would cause some insertions to take O(n) time.
631 *
632 * @param i a position known NOT to hold a stale entry. The
633 * scan starts at the element after i.
634 *
635 * @param n scan control: {@code log2(n)} cells are scanned,
636 * unless a stale entry is found, in which case
637 * {@code log2(table.length)-1} additional cells are scanned.
638 * When called from insertions, this parameter is the number
639 * of elements, but when from replaceStaleEntry, it is the
640 * table length. (Note: all this could be changed to be either
641 * more or less aggressive by weighting n instead of just
642 * using straight log n. But this version is simple, fast, and
643 * seems to work well.)
644 *
645 * @return true if any stale entries have been removed.
646 */
647 private boolean cleanSomeSlots(int i, int n) {
648 boolean removed = false;
649 Entry[] tab = table;
650 int len = tab.length;
651 do {
652 i = nextIndex(i, len);
653 Entry e = tab[i];
654 if (e != null && e.get() == null) {
655 n = len;
656 removed = true;
657 i = expungeStaleEntry(i);
|