什么是ThreadLocal,看作者的这一段话

 * This class provides thread-local variables.  These variables differ from

 * their normal counterparts in that each thread that accesses one (via its

 * {@code get} or {@code set} method) has its own, independently initialized

 * copy of the variable.  {@code ThreadLocal} instances are typically private

 * static fields in classes that wish to associate state with a thread (e.g.,

 * a user ID or Transaction ID).

每个线程都有一个独属于自己的变量,并且可以通过简单的方式进行管理。

为什么可以做到线程私有呢?

在源码Thread.java中定义了一个变量 threadLocals

    /* ThreadLocal values pertaining to this thread. This map is maintained

     * by the ThreadLocal class. */

    ThreadLocal.ThreadLocalMap threadLocals = null;

它是线程实例的一部分,不会被其它线程访问到。

重点操作

可以理解的是最终的操作落到了ThreadLocal.ThreadLocalMap threadLocals上,主要对 ThreadLocalMap所实现的操作进行讨论。

get

        private Entry getEntry(ThreadLocal<?> key) {

            int i = key.threadLocalHashCode & (table.length - 1);

            Entry e = table[i];

            if (e != null && e.get() == key)

                return e;

            else

                return getEntryAfterMiss(key, i, e);

        }

通过 Entry.value就可以获取相应 ThreadLocal的值了。

set

        private void set(ThreadLocal<?> key, Object value) {

  

            // We don't use a fast path as with get() because it is at

            // least as common to use set() to create new entries as

            // it is to replace existing ones, in which case, a fast

            // path would fail more often than not.

  

            Entry[] tab = table;

            int len = tab.length;

            int i = key.threadLocalHashCode & (len-1);

  

            for (Entry e = tab[i];

                 e != null;

                 e = tab[i = nextIndex(i, len)]) {

                ThreadLocal<?> k = e.get();

  

                if (k == key) {

                    e.value = value;

                    return;

                }

  

                if (k == null) {

                    replaceStaleEntry(key, value, i);

                    return;

                }

            }

  

            tab[i] = new Entry(key, value);

            int sz = ++size;

            if (!cleanSomeSlots(i, sz) && sz >= threshold)

                rehash();

        }

通过hash散列算法将不同的ThreadLocal存入hash table。(还没弄明白这个算法)

问题

  • hash散列算法是什么?   private static final int HASH_INCREMENT = 0x61c88647;这个特殊的数字有什么含义?
  • Entery中的key是弱引用,垃圾回收,value是强引用,这些有什么关联?
     static class Entry extends WeakReference<ThreadLocal<?>> {

            /** The value associated with this ThreadLocal. */

            Object value;

  

            Entry(ThreadLocal<?> k, Object v) {

                super(k);

                value = v;

            }

        }
posted on 2025-03-01 17:25  嗯嗯好傅  阅读(6)  评论(0)    收藏  举报