“`” 从 Thread类源代码入手。
<pre><code>public class Thread implements Runnable { ……//与此线程有关的ThreadLocal值。由ThreadLocal类维护ThreadLocal.ThreadLocalMap threadLocals = null;//与此线程有关的InheritableThreadLocal值。由InheritableThreadLocal类维护ThreadLocal.ThreadLocalMap inheritableThreadLocals = null; ……}</code></pre>
从上面<code>Thread</code>类 源代码可以看出<code>Thread</code> 类中有一个 <code>threadLocals</code> 和 一个 <code>inheritableThreadLocals</code> 变量,它们都是 <code>ThreadLocalMap</code> 类型的变量,我们可以把 <code>ThreadLocalMap</code> 理解为<code>ThreadLocal</code> 类实现的定制化的 <code>HashMap</code>。默认情况下这两个变量都是null,只有当前线程调用 <code>ThreadLocal</code> 类的 <code>set</code>或<code>get</code>方法时才创建它们,实际上调用这两个方法的时候,我们调用的是<code>ThreadLocalMap</code>类对应的 <code>get()</code>、<code>set()</code>方法。
<code>ThreadLocal</code>类的<code>set()</code>方法
<pre><code> public void set(T value) { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) map.set(this, value); else createMap(t, value); } ThreadLocalMap getMap(Thread t) { return t.threadLocals; }</code></pre>
通过上面这些内容,我们足以通过猜测得出结论:<strong>最终的变量是放在了当前线程的 <code>ThreadLocalMap</code> 中,并不是存在 <code>ThreadLocal</code> 上,ThreadLocal 可以理解为只是ThreadLocalMap的封装,传递了变量值。</strong>
<strong>每个Thread中都具备一个ThreadLocalMap,而ThreadLocalMap可以存储以ThreadLocal为key的键值对。</strong> 比如我们在同一个线程中声明了两个 <code>ThreadLocal</code> 对象的话,会使用 <code>Thread</code>内部都是使用仅有那个<code>ThreadLocalMap</code> 存放数据的,<code>ThreadLocalMap</code>的 key 就是 <code>ThreadLocal</code>对象,value 就是 <code>ThreadLocal</code> 对象调用<code>set</code>方法设置的值。<code>ThreadLocal</code> 是 map结构是为了让每个线程可以关联多个 <code>ThreadLocal</code>变量。这也就解释了ThreadLocal声明的变量为什么在每一个线程都有自己的专属本地变量。
<pre><code>public class Thread implements Runnable { ……//与此线程有关的ThreadLocal值。由ThreadLocal类维护ThreadLocal.ThreadLocalMap threadLocals = null;//与此线程有关的InheritableThreadLocal值。由InheritableThreadLocal类维护ThreadLocal.ThreadLocalMap inheritableThreadLocals = null; ……}</code></pre>
<code>ThreadLocalMap</code>是<code>ThreadLocal</code>的静态内部类。
<img src=""https://ws1.sinaimg.cn/large/006rNwoDgy1g2f47u9li2j30ka08cq43.jpg"" referrerpolicy=""no-referrer"" alt=""ThreadLocal内部类"" style=""width: 100%;"">
<pre><code> "“`
Was this helpful?
0 /
0