1 package java.lang;
  2 
  3 import java.lang.ref.WeakReference;
  4 import java.util.Objects;
  5 import java.util.concurrent.atomic.AtomicInteger;
  6 import java.util.function.Supplier;
  7 
  8 /**
  9  * This class provides thread-local variables.  These variables differ from
 10  * their normal counterparts in that each thread that accesses one (via its
 11  * {@code get} or {@code set} method) has its own, independently initialized
 12  * copy of the variable.  {@code ThreadLocal} instances are typically private
 13  * static fields in classes that wish to associate state with a thread (e.g.,
 14  * a user ID or Transaction ID).
 15  * 本类提供线程局部变量。这些变量和普通变量不同,每一个线程访问(通过get和set方法)
 16  * 的变量都是属于线程的独立初始化的一个线程局部变量的副本。线程局部变量通常是类中希望
 17  * 将状态与线程关联的私有静态域(如用户ID和事务ID)。
 18  *
 19  * <p>For example, the class below generates unique identifiers local to each
 20  * thread.
 21  * 例如,下面的类生成每个线程本地的唯一标识符。
 22  * A thread's id is assigned the first time it invokes {@code ThreadId.get()}
 23  * and remains unchanged on subsequent calls.
 24  * 一个线程的Id在该线程首次调用get方法时生成,且在后续通话中保持不变。
 25  * <pre>
 26  * import java.util.concurrent.atomic.AtomicInteger;
 27  *
 28  * public class ThreadId {
 29  *     // Atomic integer containing the next thread ID to be assigned
 30  *     private static final AtomicInteger nextId = new AtomicInteger(0);
 31  *
 32  *     // Thread local variable containing each thread's ID
 33  *     private static final ThreadLocal<Integer> threadId =
 34  *         new ThreadLocal<Integer>() {
 35  *             @Override
 36  *             protected Integer initialValue() {
 37  *                 return nextId.getAndIncrement();
 38  *         }
 39  *     };
 40  *
 41  *     // Returns the current thread's unique ID, assigning it if necessary
 42  *     public static int get() {
 43  *         return threadId.get();
 44  *     }
 45  * }
 46  * </pre>
 47  * <p>Each thread holds an implicit reference to its copy of a thread-local
 48  * variable as long as the thread is alive and the {@code ThreadLocal}
 49  * instance is accessible; after a thread goes away, all of its copies of
 50  * thread-local instances are subject to garbage collection (unless other
 51  * references to these copies exist).
 52  * 只要线程还活着,且ThreadLocal实例能够被访问,每个线程均保留其线程局部变量
 53  * 副本的隐式引用;线程死后它的所有线程局部变量副本被垃圾回收器回收(除非存在
 54  * 对这些线程局部变量副本的其他应用)
 55  *
 56  * @author Josh Bloch and Doug Lea
 57  * @since 1.2
 58  */
 59 public class ThreadLocal<T> {
 60     /**
 61      * ThreadLocals rely on per-thread linear-probe hash maps attached
 62      * to each thread (Thread.threadLocals and inheritableThreadLocals).
 63      * ThreadLocal的实例依赖于每个线程的线性探针哈希图附加到每个线程。
 64      * The ThreadLocal objects act as keys,searched via threadLocalHashCode.
 65      * ThreadLocal对象充当键,通过threadLocalHashCode搜索。
 66      * This is a custom hash code
 67      * (useful only within ThreadLocalMaps) that eliminates collisions
 68      * in the common case where consecutively constructed ThreadLocals
 69      * are used by the same threads, while remaining well-behaved in
 70      * less common cases.
 71      * 这是一个自定义哈希码(仅在ThreadLocalMaps中有用),在相同的线程使用连续构造
 72      * 的ThreadLocals的常见情况下,它消除了冲突,而在不太常见的情况下,它们表现良好。
 73      */
 74     private final int threadLocalHashCode = nextHashCode();
 75 
 76     /**
 77      * The next hash code to be given out. Updated atomically. Starts at
 78      * zero.
 79      * 下一次给出的哈希码,该值的自动更新不能被中断(原子性),值从0开始累加。
 80      */
 81     private static AtomicInteger nextHashCode =
 82             new AtomicInteger();
 83 
 84     /**
 85      * The difference between successively generated hash codes - turns
 86      * implicit sequential thread-local IDs into near-optimally spread
 87      * multiplicative hash values for power-of-two-sized tables.
 88      * 连续生成的哈希码间的差值,
 89      */
 90     private static final int HASH_INCREMENT = 0x61c88647;
 91 
 92     /**
 93      * Returns the next hash code.
 94      * 返回下一个哈希码
 95      */
 96     private static int nextHashCode() {
 97         return nextHashCode.getAndAdd(HASH_INCREMENT);
 98     }
 99 
100     /**
101      * Returns the current thread's "initial value" for this
102      * thread-local variable.  This method will be invoked the first
103      * time a thread accesses the variable with the {@link #get}
104      * method, unless the thread previously invoked the {@link #set}
105      * method, in which case the {@code initialValue} method will not
106      * be invoked for the thread.  Normally, this method is invoked at
107      * most once per thread, but it may be invoked again in case of
108      * subsequent invocations of {@link #remove} followed by {@link #get}.
109      * 翻译:
110      * 返回当前线程持有的线程局部变量副本的初始值。线程在第一次通过get方法访问局部
111      * 变量前如果没有调用过set方法为局部变量设置值,本函数就会被调用。通常每个线程
112      * 最多会调用一次本方法,但是如果在之后依次调用了remove和get方法,它可能会再次被调用。
113      *
114      * <p>This implementation simply returns {@code null}; if the
115      * programmer desires thread-local variables to have an initial
116      * value other than {@code null}, {@code ThreadLocal} must be
117      * subclassed, and this method overridden.  Typically, an
118      * anonymous inner class will be used.
119      * 本实现仅返回null,如果开发者希望线程的局部变量具体其他初始值,只能通过声明子类并
120      * 重写本方法。通常,将使用匿名内部类。(下面就有一个内部类)
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. The initial value of the variable is
130      * determined by invoking the {@code get} method on the {@code Supplier}.
131      * 创建一个线程局部变量的副本,变量的初始值是通过调用Supplier上的get方法确定的。
132      * (Supplier是一个函数式接口)
133      *
134      * @param <S>      the type of the thread local's value
135      * @param supplier the supplier to be used to determine the initial value
136      * @return a new thread local variable
137      * @throws NullPointerException if the specified supplier is null
138      * @since 1.8
139      */
140     public static <S> ThreadLocal<S> withInitial(Supplier<? extends S> supplier) {
141         return new SuppliedThreadLocal<>(supplier);
142     }
143 
144     /**
145      * 构造函数
146      * Creates a thread local variable.
147      *
148      * @see #withInitial(java.util.function.Supplier)
149      */
150     public ThreadLocal() {
151     }
152 
153     /**
154      * Returns the value in the current thread's copy of this
155      * thread-local variable.  If the variable has no value for the
156      * current thread, it is first initialized to the value returned
157      * by an invocation of the {@link #initialValue} method.
158      * 译:
159      * 返回当前线程持有的线程局部变量副本的值。如果该变量还没赋值,
160      * 则先使用initialValue方法为其赋予初始值。
161      *
162      * @return the current thread's value of this thread-local
163      */
164     public T get() {
165         //1、确定当前线程
166         Thread t = Thread.currentThread();
167         //2、
168         ThreadLocalMap map = getMap(t);
169         if (map != null) {
170             ThreadLocalMap.Entry e = map.getEntry(this);
171             if (e != null) {
172                 @SuppressWarnings("unchecked")
173                 T result = (T) e.value;
174                 return result;
175             }
176         }
177         return setInitialValue();
178     }
179 
180     /**
181      * Variant of set() to establish initialValue. Used instead
182      * of set() in case user has overridden the set() method.
183      * 译:
184      * set方法的变体,用于设置初始值。如果用户已覆盖set()方法,
185      * 请使用它代替set()。
186      *
187      * @return the initial value
188      */
189     private T setInitialValue() {
190         T value = initialValue();
191         Thread t = Thread.currentThread();
192         ThreadLocalMap map = getMap(t);
193         if (map != null)
194             map.set(this, value);
195         else
196             createMap(t, value);
197         return value;
198     }
199 
200     /**
201      * Sets the current thread's copy of this thread-local variable
202      * to the specified value.  Most subclasses will have no need to
203      * override this method, relying solely on the {@link #initialValue}
204      * method to set the values of thread-locals.
205      * 译:
206      * 设置当前线程持有的线程局部变量副本的值为指定值。大部分子类不需要重写本
207      * 方法,仅依靠initialValue方法来设置值。
208      *
209      * @param value the value to be stored in the current thread's copy of
210      *              this thread-local.
211      */
212     public void set(T value) {
213         Thread t = Thread.currentThread();
214         ThreadLocalMap map = getMap(t);
215         if (map != null)
216             map.set(this, value);
217         else
218             createMap(t, value);
219     }
220 
221     /**
222      * Removes the current thread's value for this thread-local
223      * variable.  If this thread-local variable is subsequently
224      * {@linkplain #get read} by the current thread, its value will be
225      * reinitialized by invoking its {@link #initialValue} method,
226      * unless its value is {@linkplain #set set} by the current thread
227      * in the interim.  This may result in multiple invocations of the
228      * {@code initialValue} method in the current thread.
229      * 译:
230      * 移除单前线程持有的线程本地变量的值。如果随后马上又通过get方法试图获取
231      * 这个线程本地变量的值,这个变量的值会再次通过调用initialValue方法确定,
232      * 除非在调用get方法前通过set方法设置了值就不会。这可能会导致initialValue
233      * 方法被当前线程多次调用。
234      *
235      * @since 1.5
236      */
237     public void remove() {
238         ThreadLocalMap m = getMap(Thread.currentThread());
239         if (m != null)
240             m.remove(this);
241     }
242 
243     /**
244      * Get the map associated with a ThreadLocal. Overridden in
245      * InheritableThreadLocal.
246      *
247      * @param t the current thread
248      * @return the map
249      */
250     ThreadLocalMap getMap(Thread t) {
251         return t.threadLocals;
252     }
253 
254     /**
255      * Create the map associated with a ThreadLocal. Overridden in
256      * InheritableThreadLocal.
257      *
258      * @param t          the current thread
259      * @param firstValue value for the initial entry of the map
260      */
261     void createMap(Thread t, T firstValue) {
262         t.threadLocals = new ThreadLocalMap(this, firstValue);
263     }
264 
265     /**
266      * Factory method to create map of inherited thread locals.
267      * Designed to be called only from Thread constructor.
268      *
269      * @param parentMap the map associated with parent thread
270      * @return a map containing the parent's inheritable bindings
271      */
272     static ThreadLocalMap createInheritedMap(ThreadLocalMap parentMap) {
273         return new ThreadLocalMap(parentMap);
274     }
275 
276     /**
277      * Method childValue is visibly defined in subclass
278      * InheritableThreadLocal, but is internally defined here for the
279      * sake of providing createInheritedMap factory method without
280      * needing to subclass the map class in InheritableThreadLocal.
281      * This technique is preferable to the alternative of embedding
282      * instanceof tests in methods.
283      */
284     T childValue(T parentValue) {
285         throw new UnsupportedOperationException();
286     }
287 
288     /**
289      * An extension of ThreadLocal that obtains its initial value from
290      * the specified {@code Supplier}.
291      * SuppliedThreadLocal类拓展了ThreadLocal类,该类重写了initialValue函数,
292      * 用于从指定的Supplier获取初始值。
293      */
294     static final class SuppliedThreadLocal<T> extends ThreadLocal<T> {
295 
296         /**
297          * Supplier<T>是一个函数式接口
298          */
299         private final Supplier<? extends T> supplier;
300 
301         /**
302          * 构造函数
303          *
304          * @param supplier - 一个函数式接口,用来返回线程本地变量的初始值
305          */
306         SuppliedThreadLocal(Supplier<? extends T> supplier) {
307             /**
308              *     public static <T> T requireNonNull(T obj) {
309              *         if (obj == null)
310              *             throw new NullPointerException();
311              *         return obj;
312              *     }
313              */
314             this.supplier = Objects.requireNonNull(supplier);
315         }
316 
317         /**
318          * 这里很关键,需要去看看Supplier接口的源码。
319          */
320         @Override
321         protected T initialValue() {
322             return supplier.get();
323         }
324     }
325 
326     /**
327      * ThreadLocalMap is a customized hash map suitable only for
328      * maintaining thread local values. No operations are exported
329      * outside of the ThreadLocal class. The class is package private to
330      * allow declaration of fields in class Thread.  To help deal with
331      * very large and long-lived usages, the hash table entries use
332      * WeakReferences for keys. However, since reference queues are not
333      * used, stale entries are guaranteed to be removed only when
334      * the table starts running out of space.
335      * 译:
336      * ThreadLocalMap是自定义的HashMap,仅适用于维护线程局部变量的值。
337      * 没有操作导出到ThreadLocal类之外。这个类是包私有的,用于Thread类
338      * 域声明。为了处理存储空间消耗大,使用时间长的使用情况,这个HashTable
339      * 使用WeakReferences(弱引用)作为键。但是,由于未使用参考队列,因此
340      * 仅在表开始空间不足时,才保证删除过时的条目。
341      */
342     static class ThreadLocalMap {
343 
344         /**
345          * The entries in this hash map extend WeakReference, using
346          * its main ref field as the key (which is always a
347          * ThreadLocal object).  Note that null keys (i.e. entry.get()
348          * == null) mean that the key is no longer referenced, so the
349          * entry can be expunged from table.  Such entries are referred to
350          * as "stale entries" in the code that follows.
351          * 译:
352          * 该哈希表中的条目是WeakReference子类的对象,以其主域作为键(大多数情
353          * 况下是一个ThreadLocal对象)。需要注意,当以null作为键时,意味着这个
354          * 键已经不再被引用,因此这个键所在的条目能被表移除。这样的条目我们在下文
355          * 中称为“过时的条目”
356          */
357         static class Entry extends WeakReference<ThreadLocal<?>> {
358             /**
359              * The value associated with this ThreadLocal.
360              * 与ThreadLocal相关联的值
361              */
362             Object value;
363 
364             /**
365              * @param k - 以线程作为键
366              * @param v - 线程持有的threal-local变量副本的值
367              */
368             Entry(ThreadLocal<?> k, Object v) {
369                 super(k);
370                 value = v;
371             }
372         }
373 
374         /**
375          * The initial capacity -- MUST be a power of two.
376          * 初始容量——必须是2的幂
377          */
378         private static final int INITIAL_CAPACITY = 16;
379 
380         /**
381          * The table, resized as necessary.
382          * table.length MUST always be a power of two.
383          * 译:
384          * 表在必要的时候会扩容,表的大小必须是2的幂
385          */
386         private Entry[] table;
387 
388         /**
389          * The number of entries in the table.
390          * 表中条目(键值对)的数量
391          */
392         private int size = 0;
393 
394         /**
395          * the next size value at which to resize.
396          * 下一次调整表的大小时要增加的值
397          */
398         private int threshold; // Default to 0
399 
400         /**
401          * Set the resize threshold to maintain at worst a 2/3 load factor.
402          * 从这里可以看出,每次扩容,容量增加2/3。
403          */
404         private void setThreshold(int len) {
405             threshold = len * 2 / 3;
406         }
407 
408         /**
409          * Increment i modulo len.
410          */
411         private static int nextIndex(int i, int len) {
412             return ((i + 1 < len) ? i + 1 : 0);
413         }
414 
415         /**
416          * Decrement i modulo len.
417          */
418         private static int prevIndex(int i, int len) {
419             return ((i - 1 >= 0) ? i - 1 : len - 1);
420         }
421 
422         /**
423          * Construct a new map initially containing (firstKey, firstValue).
424          * ThreadLocalMaps are constructed lazily, so we only create
425          * one when we have at least one entry to put in it.
426          * 译:
427          * 构造一个最初包含以下内容的新Map。ThreadLocalMaps是延迟创建的,所以
428          * 只有当至少要添加一条条目时才创建一个。
429          */
430         ThreadLocalMap(ThreadLocal<?> firstKey, Object firstValue) {
431             table = new Entry[INITIAL_CAPACITY];
432             int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY - 1);
433             table[i] = new Entry(firstKey, firstValue);
434             size = 1;
435             setThreshold(INITIAL_CAPACITY);
436         }
437 
438         /**
439          * Construct a new map including all Inheritable ThreadLocals
440          * from given parent map. Called only by createInheritedMap.
441          *
442          * @param parentMap the map associated with parent thread.
443          */
444         private ThreadLocalMap(ThreadLocalMap parentMap) {
445             Entry[] parentTable = parentMap.table;
446             int len = parentTable.length;
447             setThreshold(len);
448             table = new Entry[len];
449 
450             for (int j = 0; j < len; j++) {
451                 Entry e = parentTable[j];
452                 if (e != null) {
453                     @SuppressWarnings("unchecked")
454                     ThreadLocal<Object> key = (ThreadLocal<Object>) e.get();
455                     if (key != null) {
456                         Object value = key.childValue(e.value);
457                         Entry c = new Entry(key, value);
458                         int h = key.threadLocalHashCode & (len - 1);
459                         while (table[h] != null)
460                             h = nextIndex(h, len);
461                         table[h] = c;
462                         size++;
463                     }
464                 }
465             }
466         }
467 
468         /**
469          * Get the entry associated with key.  This method
470          * itself handles only the fast path: a direct hit of existing
471          * key. It otherwise relays to getEntryAfterMiss.  This is
472          * designed to maximize performance for direct hits, in part
473          * by making this method readily inlinable.
474          * 译:
475          * 获取键关联的条目。
476          * 理解:
477          * 散列表中通过哈希函数和键计算哈希码,使用哈希码来决定数据存储的位置,
478          * 不同的键通过哈希函数可能计算出相同的哈希码,这被称为“冲突”。遇到冲突
479          * 时需要使用某种“冲突解决策略”重新确定一个哈希码,本函数假设没有冲突,
480          * 尝试通过计算出来的哈希码直接取值。事实上好的哈希算法计算出来的哈希码
481          * 分布的比较均匀,即很少发生冲突。
482          *
483          * @param key the thread local object
484          * @return the entry associated with key, or null if no such
485          */
486         private Entry getEntry(ThreadLocal<?> key) {
487             //1、尝试直接取值
488             int i = key.threadLocalHashCode & (table.length - 1);
489             Entry e = table[i];
490             if (e != null && e.get() == key)
491                 return e;
492             else
493                 return getEntryAfterMiss(key, i, e);//2、冲突解决方案
494         }
495 
496         /**
497          * Version of getEntry method for use when key is not found in
498          * its direct hash slot.
499          *
500          * @param key the thread local object
501          * @param i   the table index for key's hash code
502          * @param e   the entry at table[i]
503          * @return the entry associated with key, or null if no such
504          */
505         private Entry getEntryAfterMiss(ThreadLocal<?> key, int i, Entry e) {
506             Entry[] tab = table;
507             int len = tab.length;
508 
509             while (e != null) {
510                 ThreadLocal<?> k = e.get();
511                 if (k == key)
512                     return e;
513                 if (k == null)
514                     expungeStaleEntry(i);
515                 else
516                     i = nextIndex(i, len);
517                 e = tab[i];
518             }
519             return null;
520         }
521 
522         /**
523          * Set the value associated with key.
524          * 设置与键关联的值
525          *
526          * @param key   the thread local object
527          * @param value the value to be set
528          */
529         private void set(ThreadLocal<?> key, Object value) {
530 
531             // We don't use a fast path as with get() because it is at
532             // least as common to use set() to create new entries as
533             // it is to replace existing ones, in which case, a fast
534             // path would fail more often than not.
535 
536             Entry[] tab = table;
537             int len = tab.length;
538             int i = key.threadLocalHashCode & (len - 1);
539 
540             for (Entry e = tab[i];
541                  e != null;
542                  e = tab[i = nextIndex(i, len)]) {
543                 ThreadLocal<?> k = e.get();
544 
545                 if (k == key) {
546                     e.value = value;
547                     return;
548                 }
549 
550                 if (k == null) {
551                     replaceStaleEntry(key, value, i);
552                     return;
553                 }
554             }
555 
556             tab[i] = new Entry(key, value);
557             int sz = ++size;
558             if (!cleanSomeSlots(i, sz) && sz >= threshold)
559                 rehash();
560         }
561 
562         /**
563          * Remove the entry for key.
564          */
565         private void remove(ThreadLocal<?> key) {
566             Entry[] tab = table;
567             int len = tab.length;
568             int i = key.threadLocalHashCode & (len - 1);
569             for (Entry e = tab[i];
570                  e != null;
571                  e = tab[i = nextIndex(i, len)]) {
572                 if (e.get() == key) {
573                     e.clear();
574                     expungeStaleEntry(i);
575                     return;
576                 }
577             }
578         }
579 
580         /**
581          * Replace a stale entry encountered during a set operation
582          * with an entry for the specified key.  The value passed in
583          * the value parameter is stored in the entry, whether or not
584          * an entry already exists for the specified key.
585          * <p>
586          * As a side effect, this method expunges all stale entries in the
587          * "run" containing the stale entry.  (A run is a sequence of entries
588          * between two null slots.)
589          *
590          * @param key       the key
591          * @param value     the value to be associated with key
592          * @param staleSlot index of the first stale entry encountered while
593          *                  searching for key.
594          */
595         private void replaceStaleEntry(ThreadLocal<?> key, Object value,
596                                        int staleSlot) {
597             Entry[] tab = table;
598             int len = tab.length;
599             Entry e;
600 
601             // Back up to check for prior stale entry in current run.
602             // We clean out whole runs at a time to avoid continual
603             // incremental rehashing due to garbage collector freeing
604             // up refs in bunches (i.e., whenever the collector runs).
605             int slotToExpunge = staleSlot;
606             for (int i = prevIndex(staleSlot, len);
607                  (e = tab[i]) != null;
608                  i = prevIndex(i, len))
609                 if (e.get() == null)
610                     slotToExpunge = i;
611 
612             // Find either the key or trailing null slot of run, whichever
613             // occurs first
614             for (int i = nextIndex(staleSlot, len);
615                  (e = tab[i]) != null;
616                  i = nextIndex(i, len)) {
617                 ThreadLocal<?> k = e.get();
618 
619                 // If we find key, then we need to swap it
620                 // with the stale entry to maintain hash table order.
621                 // The newly stale slot, or any other stale slot
622                 // encountered above it, can then be sent to expungeStaleEntry
623                 // to remove or rehash all of the other entries in run.
624                 if (k == key) {
625                     e.value = value;
626 
627                     tab[i] = tab[staleSlot];
628                     tab[staleSlot] = e;
629 
630                     // Start expunge at preceding stale entry if it exists
631                     if (slotToExpunge == staleSlot)
632                         slotToExpunge = i;
633                     cleanSomeSlots(expungeStaleEntry(slotToExpunge), len);
634                     return;
635                 }
636 
637                 // If we didn't find stale entry on backward scan, the
638                 // first stale entry seen while scanning for key is the
639                 // first still present in the run.
640                 if (k == null && slotToExpunge == staleSlot)
641                     slotToExpunge = i;
642             }
643 
644             // If key not found, put new entry in stale slot
645             tab[staleSlot].value = null;
646             tab[staleSlot] = new Entry(key, value);
647 
648             // If there are any other stale entries in run, expunge them
649             if (slotToExpunge != staleSlot)
650                 cleanSomeSlots(expungeStaleEntry(slotToExpunge), len);
651         }
652 
653         /**
654          * Expunge a stale entry by rehashing any possibly colliding entries
655          * lying between staleSlot and the next null slot.  this also expunges
656          * any other stale entries encountered before the trailing null.  See
657          * Knuth, Section 6.4
658          * 译:
659          * 通过重新散列位于staleSlot和下一个null插槽之间的任何可能冲突的条目来清除
660          * 陈旧的条目。这还将删除尾随null之前遇到的所有其他过时的条目。
661          *
662          * @param staleSlot index of slot known to have null key
663          * @return the index of the next null slot after staleSlot
664          * (all between staleSlot and this slot will have been checked
665          * for expunging).
666          */
667         private int expungeStaleEntry(int staleSlot) {
668             Entry[] tab = table;
669             int len = tab.length;
670 
671             // expunge entry at staleSlot
672             tab[staleSlot].value = null;
673             tab[staleSlot] = null;
674             size--;
675 
676             // Rehash until we encounter null
677             Entry e;
678             int i;
679             for (i = nextIndex(staleSlot, len);
680                  (e = tab[i]) != null;
681                  i = nextIndex(i, len)) {
682                 ThreadLocal<?> k = e.get();
683                 if (k == null) {
684                     e.value = null;
685                     tab[i] = null;
686                     size--;
687                 } else {
688                     int h = k.threadLocalHashCode & (len - 1);
689                     if (h != i) {
690                         tab[i] = null;
691 
692                         // Unlike Knuth 6.4 Algorithm R, we must scan until
693                         // null because multiple entries could have been stale.
694                         while (tab[h] != null)
695                             h = nextIndex(h, len);
696                         tab[h] = e;
697                     }
698                 }
699             }
700             return i;
701         }
702 
703         /**
704          * Heuristically scan some cells looking for stale entries.
705          * This is invoked when either a new element is added, or
706          * another stale one has been expunged. It performs a
707          * logarithmic number of scans, as a balance between no
708          * scanning (fast but retains garbage) and a number of scans
709          * proportional to number of elements, that would find all
710          * garbage but would cause some insertions to take O(n) time.
711          * 译:
712          * 启发式扫描某些单元以查找陈旧条目。当添加了新元素或已删除另一旧
713          * 元素时,将调用此方法。它执行对数扫描,作为无扫描(快速但保留垃
714          * 圾)和与元素数量成正比的扫描数量之间的平衡,这会发现所有垃圾,
715          * 但会导致某些插入花费O(n)时间。
716          *
717          * @param i a position known NOT to hold a stale entry. The
718          *          scan starts at the element after i.
719          * @param n scan control: {@code log2(n)} cells are scanned,
720          *          unless a stale entry is found, in which case
721          *          {@code log2(table.length)-1} additional cells are scanned.
722          *          When called from insertions, this parameter is the number
723          *          of elements, but when from replaceStaleEntry, it is the
724          *          table length. (Note: all this could be changed to be either
725          *          more or less aggressive by weighting n instead of just
726          *          using straight log n. But this version is simple, fast, and
727          *          seems to work well.)
728          * @return true if any stale entries have been removed.
729          */
730         private boolean cleanSomeSlots(int i, int n) {
731             boolean removed = false;
732             Entry[] tab = table;
733             int len = tab.length;
734             do {
735                 i = nextIndex(i, len);
736                 Entry e = tab[i];
737                 if (e != null && e.get() == null) {
738                     n = len;
739                     removed = true;
740                     i = expungeStaleEntry(i);
741                 }
742             } while ((n >>>= 1) != 0);
743             return removed;
744         }
745 
746         /**
747          * Re-pack and/or re-size the table. First scan the entire
748          * table removing stale entries. If this doesn't sufficiently
749          * shrink the size of the table, double the table size.
750          * 译:
751          * 重新包装和/或调整表大小。首先扫描整个表,删除陈旧的条目。
752          * 如果这还不足以缩小表格的大小,请将表格大小加倍。
753          */
754         private void rehash() {
755             expungeStaleEntries();
756 
757             // Use lower threshold for doubling to avoid hysteresis
758             if (size >= threshold - threshold / 4)
759                 resize();
760         }
761 
762         /**
763          * Double the capacity of the table.
764          * 使表的容积几倍。
765          */
766         private void resize() {
767             Entry[] oldTab = table;
768             int oldLen = oldTab.length;
769             int newLen = oldLen * 2;
770             Entry[] newTab = new Entry[newLen];
771             int count = 0;
772 
773             for (int j = 0; j < oldLen; ++j) {
774                 Entry e = oldTab[j];
775                 if (e != null) {
776                     ThreadLocal<?> k = e.get();
777                     if (k == null) {
778                         e.value = null; // Help the GC
779                     } else {
780                         int h = k.threadLocalHashCode & (newLen - 1);
781                         while (newTab[h] != null)
782                             h = nextIndex(h, newLen);
783                         newTab[h] = e;
784                         count++;
785                     }
786                 }
787             }
788 
789             setThreshold(newLen);
790             size = count;
791             table = newTab;
792         }
793 
794         /**
795          * Expunge all stale entries in the table.
796          * 清除表中所有过时条目
797          */
798         private void expungeStaleEntries() {
799             Entry[] tab = table;
800             int len = tab.length;
801             for (int j = 0; j < len; j++) {
802                 Entry e = tab[j];
803                 if (e != null && e.get() == null)
804                     expungeStaleEntry(j);
805             }
806         }
807     }
808 }

 

 1 /*
 2  * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
 3  * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 4  *
 5  *
 6  *
 7  *
 8  *
 9  *
10  *
11  *
12  *
13  *
14  *
15  *
16  *
17  *
18  *
19  *
20  *
21  *
22  *
23  *
24  */
25 package java.util.function;
26 
27 /**
28  * 该类函数式接口应用于支持Lambda表达式的API中,
29  * Supplier接口用于提供一个T类对象。
30  */
31 
32 /**
33  * Represents a supplier of results.
34  * 代表结果的提供者
35  *
36  * <p>There is no requirement that a new or distinct result be returned each
37  * time the supplier is invoked.
38  * 并不要求每次调用都返回一个新的或者不同的结果。
39  *
40  * <p>This is a <a href="package-summary.html">functional interface</a>
41  * whose functional method is {@link #get()}.
42  *
43  * @param <T> the type of results supplied by this supplier
44  * @since 1.8
45  */
46 @FunctionalInterface
47 public interface Supplier<T> {
48 
49     /**
50      * Gets a result.
51      *
52      * @return a result
53      */
54     T get();
55 }