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
85 /**
86 * The next hash code to be given out. Updated atomically. Starts at
87 * zero.
88 */
89 private static AtomicInteger nextHashCode =
90 new AtomicInteger();
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;
150 return result;
151 }
152 }
153 return setInitialValue();
154 }
155
156 /**
157 * Variant of set() to establish initialValue. Used instead
158 * of set() in case user has overridden the set() method.
159 *
160 * @return the initial value
161 */
162 private T setInitialValue() {
163 T value = initialValue();
164 Thread t = Thread.currentThread();
165 ThreadLocalMap map = getMap(t);
166 if (map != null)
167 map.set(this, value);
168 else
169 createMap(t, value);
170 return value;
171 }
172
173 /**
174 * Sets the current thread's copy of this thread-local variable
175 * to the specified value. Most subclasses will have no need to
176 * override this method, relying solely on the {@link #initialValue}
177 * method to set the values of thread-locals.
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
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 * The initial value of the variable is set by (1) calling the
72 * {@code initialValue method}, (2) obtaining it from a {@code Supplier<T>}
73 * which has been provided via the
74 * constructor, or (3) by calling the {@code set} method.
75 *
76 * If (1) is used and an initial value other than the default of null is required,
77 * the {@code initialValue} method is typically overridden with an
78 * anonymous-inner class.
79 *
80 * @author Josh Bloch and Doug Lea
81 * @since 1.2
82 */
83 public class ThreadLocal<T> {
84 /**
85 * ThreadLocals rely on per-thread linear-probe hash maps attached
86 * to each thread (Thread.threadLocals and
87 * inheritableThreadLocals). The ThreadLocal objects act as keys,
88 * searched via threadLocalHashCode. This is a custom hash code
89 * (useful only within ThreadLocalMaps) that eliminates collisions
90 * in the common case where consecutively constructed ThreadLocals
91 * are used by the same threads, while remaining well-behaved in
92 * less common cases.
93 */
94 private final int threadLocalHashCode = nextHashCode();
95
96 /**
97 * The next hash code to be given out. Updated atomically. Starts at
98 * zero.
99 */
100 private static AtomicInteger nextHashCode =
101 new AtomicInteger();
102
103 /**
104 * The difference between successively generated hash codes - turns
105 * implicit sequential thread-local IDs into near-optimally spread
106 * multiplicative hash values for power-of-two-sized tables.
107 */
108 private static final int HASH_INCREMENT = 0x61c88647;
109
110 /**
111 * Supplied by the invoker of the constructor to set the initial value
112 */
113 private final Supplier<T> supplier;
114
115 /**
116 * Returns the next hash code.
117 */
118 private static int nextHashCode() {
119 return nextHashCode.getAndAdd(HASH_INCREMENT);
120 }
121
122 /**
123 * Returns the current thread's "initial value" for this
124 * thread-local variable unless a {@code Supplier<T>} has been passed
125 * to the constructor, in which case the Supplier is consulted in
126 * preference to this method. This method will be invoked the first
127 * time a thread accesses the variable with the {@link #get}
128 * method, unless the thread previously invoked the {@link #set}
129 * method, in which case the {@code initialValue} method will not
130 * be invoked for the thread. Normally, this method is invoked at
131 * most once per thread, but it may be invoked again in case of
132 * subsequent invocations of {@link #remove} followed by {@link #get}.
133 *
134 * <p>This implementation simply returns {@code null}
135 *
136 * @return the initial value for this thread-local
137 */
138 protected T initialValue() {
139 return null;
140 }
141
142 /**
143 * Creates a thread local variable. The initial value of the variable is
144 * provided by calling the {@code intialValue} method.
145 */
146 public ThreadLocal() {
147 supplier = null;
148 }
149
150 /**
151 * Creates a thread local variable. The initial value of the variable is
152 * determined by invoking the {@code get} method on the supplier.
153 *
154 * @param supplier the supplier to be used to determine the initial value
155 */
156 public ThreadLocal(Supplier<T> supplier) {
157 this.supplier = Objects.requireNonNull(supplier);
158 }
159
160 /**
161 * Returns the value in the current thread's copy of this
162 * thread-local variable. If the variable has no value for the
163 * current thread, it is first initialized to the value returned
164 * by an invocation of the {@link #initialValue} method.
165 *
166 * @return the current thread's value of this thread-local
167 */
168 public T get() {
169 Thread t = Thread.currentThread();
170 ThreadLocalMap map = getMap(t);
171 if (map != null) {
172 ThreadLocalMap.Entry e = map.getEntry(this);
173 if (e != null) {
174 @SuppressWarnings("unchecked")
175 T result = (T)e.value;
176 return result;
177 }
178 }
179 return setInitialValue();
180 }
181
182 /**
183 * Variant of set() to establish initialValue. Used instead
184 * of set() in case user has overridden the set() method.
185 *
186 * @return the initial value
187 */
188 private T setInitialValue() {
189 T value = (supplier != null ? supplier.get() : initialValue());
190 Thread t = Thread.currentThread();
191 ThreadLocalMap map = getMap(t);
192 if (map != null)
193 map.set(this, value);
194 else
195 createMap(t, value);
196 return value;
197 }
198
199 /**
200 * Sets the current thread's copy of this thread-local variable
201 * to the specified value. Most subclasses will have no need to
202 * override this method, relying solely on the {@link #initialValue}
203 * method to set the values of thread-locals.
204 *
205 * @param value the value to be stored in the current thread's copy of
206 * this thread-local.
207 */
208 public void set(T value) {
209 Thread t = Thread.currentThread();
210 ThreadLocalMap map = getMap(t);
211 if (map != null)
212 map.set(this, value);
213 else
214 createMap(t, value);
215 }
216
217 /**
218 * Removes the current thread's value for this thread-local
219 * variable. If this thread-local variable is subsequently
220 * {@linkplain #get read} by the current thread, its value will be
221 * reinitialized by invoking its {@link #initialValue} method,
222 * unless its value is {@linkplain #set set} by the current thread
223 * in the interim. This may result in multiple invocations of the
224 * {@code initialValue} method in the current thread.
225 *
226 * @since 1.5
227 */
228 public void remove() {
229 ThreadLocalMap m = getMap(Thread.currentThread());
230 if (m != null)
231 m.remove(this);
232 }
233
234 /**
235 * Get the map associated with a ThreadLocal. Overridden in
236 * InheritableThreadLocal.
237 *
238 * @param t the current thread
239 * @return the map
240 */
241 ThreadLocalMap getMap(Thread t) {
242 return t.threadLocals;
243 }
244
608 h = nextIndex(h, len);
609 tab[h] = e;
610 }
611 }
612 }
613 return i;
614 }
615
616 /**
617 * Heuristically scan some cells looking for stale entries.
618 * This is invoked when either a new element is added, or
619 * another stale one has been expunged. It performs a
620 * logarithmic number of scans, as a balance between no
621 * scanning (fast but retains garbage) and a number of scans
622 * proportional to number of elements, that would find all
623 * garbage but would cause some insertions to take O(n) time.
624 *
625 * @param i a position known NOT to hold a stale entry. The
626 * scan starts at the element after i.
627 *
628 * @param n scan control: {@code log2(n)} cells are scanned,
629 * unless a stale entry is found, in which case
630 * {@code log2(table.length)-1} additional cells are scanned.
631 * When called from insertions, this parameter is the number
632 * of elements, but when from replaceStaleEntry, it is the
633 * table length. (Note: all this could be changed to be either
634 * more or less aggressive by weighting n instead of just
635 * using straight log n. But this version is simple, fast, and
636 * seems to work well.)
637 *
638 * @return true if any stale entries have been removed.
639 */
640 private boolean cleanSomeSlots(int i, int n) {
641 boolean removed = false;
642 Entry[] tab = table;
643 int len = tab.length;
644 do {
645 i = nextIndex(i, len);
646 Entry e = tab[i];
647 if (e != null && e.get() == null) {
648 n = len;
649 removed = true;
650 i = expungeStaleEntry(i);
|