JDK源码:InheritableThreadLocal实现原理

一.ThreadLocal

    Thread中有一个ThreadLocalMap类型的属性,threadLocals:

 

<span style="color:#f8f8f2"><code class="language-java">​ThreadLocal<span style="color:#f8f8f2">.</span>ThreadLocalMap threadLocals <span style="color:#f8f8f2">=</span> <span style="color:#f92672">null</span><span style="color:#f8f8f2">;</span></code></span>

    ThreadLocal的 set() 方法:拿到当前线程的 threadLocals,然后往其中塞值,key是ThreadLocal本身,value是塞入的值

取出Map的时候,如果为空,则初始化Map。

<span style="color:#333333"><span style="color:#f8f8f2"><code class="language-java">    <span style="color:#66d9ef"><span style="color:#f92672">public</span></span> <span style="color:#66d9ef"><span style="color:#f92672">void</span></span> <span style="color:#e6db74"><span style="color:#a6e22e">set</span></span><span style="color:#f8f8f2"><span style="color:#f8f8f2">(</span></span><span style="color:#f8f8f2">T value</span><span style="color:#f8f8f2"><span style="color:#f8f8f2">)</span></span> <span style="color:#f8f8f2">{</span>
        Thread t <span style="color:#f8f8f2">=</span> Thread<span style="color:#f8f8f2">.</span><span style="color:#e6db74">currentThread</span><span style="color:#f8f8f2">(</span><span style="color:#f8f8f2">)</span><span style="color:#f8f8f2">;</span>
        ThreadLocalMap map <span style="color:#f8f8f2">=</span> <span style="color:#e6db74">getMap</span><span style="color:#f8f8f2">(</span>t<span style="color:#f8f8f2">)</span><span style="color:#f8f8f2">;</span>
        <span style="color:#66d9ef"><span style="color:#f92672">if</span></span> <span style="color:#f8f8f2">(</span>map <span style="color:#f8f8f2">!=</span> <span style="color:#f92672">null</span><span style="color:#f8f8f2">)</span>
            map<span style="color:#f8f8f2">.</span><span style="color:#e6db74">set</span><span style="color:#f8f8f2">(</span><span style="color:#66d9ef"><span style="color:#f92672">this</span></span><span style="color:#f8f8f2">,</span> value<span style="color:#f8f8f2">)</span><span style="color:#f8f8f2">;</span>
        <span style="color:#66d9ef"><span style="color:#f92672">else</span></span>
            <span style="color:#e6db74">createMap</span><span style="color:#f8f8f2">(</span>t<span style="color:#f8f8f2">,</span> value<span style="color:#f8f8f2">)</span><span style="color:#f8f8f2">;</span>
    <span style="color:#f8f8f2">}</span>
    ThreadLocalMap <span style="color:#e6db74"><span style="color:#a6e22e">getMap</span></span><span style="color:#f8f8f2"><span style="color:#f8f8f2">(</span></span><span style="color:#f8f8f2">Thread t</span><span style="color:#f8f8f2"><span style="color:#f8f8f2">)</span></span> <span style="color:#f8f8f2">{</span>
        <span style="color:#66d9ef"><span style="color:#f92672">return</span></span> t<span style="color:#f8f8f2">.</span>threadLocals<span style="color:#f8f8f2">;</span>
    <span style="color:#f8f8f2">}</span>
    <span style="color:#66d9ef"><span style="color:#f92672">void</span></span> <span style="color:#e6db74"><span style="color:#a6e22e">createMap</span></span><span style="color:#f8f8f2"><span style="color:#f8f8f2">(</span></span><span style="color:#f8f8f2">Thread t</span><span style="color:#f8f8f2"><span style="color:#f8f8f2">,</span></span><span style="color:#f8f8f2"> T firstValue</span><span style="color:#f8f8f2"><span style="color:#f8f8f2">)</span></span> <span style="color:#f8f8f2">{</span>
        t<span style="color:#f8f8f2">.</span>threadLocals <span style="color:#f8f8f2">=</span> <span style="color:#66d9ef"><span style="color:#f92672">new</span></span> ThreadLocalMap<span style="color:#f8f8f2">(</span><span style="color:#66d9ef"><span style="color:#f92672">this</span></span><span style="color:#f8f8f2">,</span> firstValue<span style="color:#f8f8f2">)</span><span style="color:#f8f8f2">;</span>
    <span style="color:#f8f8f2">}</span></code></span></span>

    ThreadLocal的 get() 方法:从线程中拿出threadLocals,如果不为空,从map中拿出键值对。如果Map为空或者没有拿到值,则直接返回null。

<span style="color:#333333"><span style="color:#f8f8f2"><code class="language-java">    <span style="color:#66d9ef"><span style="color:#f92672">public</span></span> T <span style="color:#e6db74"><span style="color:#a6e22e">get</span></span><span style="color:#f8f8f2"><span style="color:#f8f8f2">(</span></span><span style="color:#f8f8f2"><span style="color:#f8f8f2">)</span></span> <span style="color:#f8f8f2">{</span>
        Thread t <span style="color:#f8f8f2">=</span> Thread<span style="color:#f8f8f2">.</span><span style="color:#e6db74">currentThread</span><span style="color:#f8f8f2">(</span><span style="color:#f8f8f2">)</span><span style="color:#f8f8f2">;</span>
        ThreadLocalMap map <span style="color:#f8f8f2">=</span> <span style="color:#e6db74">getMap</span><span style="color:#f8f8f2">(</span>t<span style="color:#f8f8f2">)</span><span style="color:#f8f8f2">;</span><span style="color:slategray"><span style="color:#75715e">// getMap方法,被InheritableThreadLocal重写了</span></span>
        <span style="color:#66d9ef"><span style="color:#f92672">if</span></span> <span style="color:#f8f8f2">(</span>map <span style="color:#f8f8f2">!=</span> <span style="color:#f92672">null</span><span style="color:#f8f8f2">)</span> <span style="color:#f8f8f2">{</span>
            ThreadLocalMap<span style="color:#f8f8f2">.</span>Entry e <span style="color:#f8f8f2">=</span> map<span style="color:#f8f8f2">.</span><span style="color:#e6db74">getEntry</span><span style="color:#f8f8f2">(</span><span style="color:#66d9ef"><span style="color:#f92672">this</span></span><span style="color:#f8f8f2">)</span><span style="color:#f8f8f2">;</span>
            <span style="color:#66d9ef"><span style="color:#f92672">if</span></span> <span style="color:#f8f8f2">(</span>e <span style="color:#f8f8f2">!=</span> <span style="color:#f92672">null</span><span style="color:#f8f8f2">)</span> <span style="color:#f8f8f2">{</span>
                <span style="color:#75715e">@</span><span style="color:#e6db74"><span style="color:#75715e">SuppressWarnings</span></span><span style="color:#f8f8f2">(</span><span style="color:#a6e22e"><span style="color:#e6db74">"unchecked"</span></span><span style="color:#f8f8f2">)</span>
                T result <span style="color:#f8f8f2">=</span> <span style="color:#f8f8f2">(</span>T<span style="color:#f8f8f2">)</span>e<span style="color:#f8f8f2">.</span>value<span style="color:#f8f8f2">;</span>
                <span style="color:#66d9ef"><span style="color:#f92672">return</span></span> result<span style="color:#f8f8f2">;</span>
            <span style="color:#f8f8f2">}</span>
        <span style="color:#f8f8f2">}</span>
        <span style="color:#66d9ef"><span style="color:#f92672">return</span></span> <span style="color:#e6db74">setInitialValue</span><span style="color:#f8f8f2">(</span><span style="color:#f8f8f2">)</span><span style="color:#f8f8f2">;</span><span style="color:slategray"><span style="color:#75715e">// map为空 or 没有取到值</span></span>
    <span style="color:#f8f8f2">}</span>
    <span style="color:#66d9ef"><span style="color:#f92672">private</span></span> T <span style="color:#e6db74"><span style="color:#a6e22e">setInitialValue</span></span><span style="color:#f8f8f2"><span style="color:#f8f8f2">(</span></span><span style="color:#f8f8f2"><span style="color:#f8f8f2">)</span></span> <span style="color:#f8f8f2">{</span>
        T value <span style="color:#f8f8f2">=</span> <span style="color:#e6db74">initialValue</span><span style="color:#f8f8f2">(</span><span style="color:#f8f8f2">)</span><span style="color:#f8f8f2">;</span>
        Thread t <span style="color:#f8f8f2">=</span> Thread<span style="color:#f8f8f2">.</span><span style="color:#e6db74">currentThread</span><span style="color:#f8f8f2">(</span><span style="color:#f8f8f2">)</span><span style="color:#f8f8f2">;</span>
        ThreadLocalMap map <span style="color:#f8f8f2">=</span> <span style="color:#e6db74">getMap</span><span style="color:#f8f8f2">(</span>t<span style="color:#f8f8f2">)</span><span style="color:#f8f8f2">;</span>
        <span style="color:#66d9ef"><span style="color:#f92672">if</span></span> <span style="color:#f8f8f2">(</span>map <span style="color:#f8f8f2">!=</span> <span style="color:#f92672">null</span><span style="color:#f8f8f2">)</span>
            map<span style="color:#f8f8f2">.</span><span style="color:#e6db74">set</span><span style="color:#f8f8f2">(</span><span style="color:#66d9ef"><span style="color:#f92672">this</span></span><span style="color:#f8f8f2">,</span> value<span style="color:#f8f8f2">)</span><span style="color:#f8f8f2">;</span>
        <span style="color:#66d9ef"><span style="color:#f92672">else</span></span>
            <span style="color:#e6db74">createMap</span><span style="color:#f8f8f2">(</span>t<span style="color:#f8f8f2">,</span> value<span style="color:#f8f8f2">)</span><span style="color:#f8f8f2">;</span>
        <span style="color:#66d9ef"><span style="color:#f92672">return</span></span> value<span style="color:#f8f8f2">;</span>
    <span style="color:#f8f8f2">}</span>
    <span style="color:#66d9ef"><span style="color:#f92672">protected</span></span> T <span style="color:#e6db74"><span style="color:#a6e22e">initialValue</span></span><span style="color:#f8f8f2"><span style="color:#f8f8f2">(</span></span><span style="color:#f8f8f2"><span style="color:#f8f8f2">)</span></span> <span style="color:#f8f8f2">{</span>
        <span style="color:#66d9ef"><span style="color:#f92672">return</span></span> <span style="color:#f92672">null</span><span style="color:#f8f8f2">;</span>
    <span style="color:#f8f8f2">}</span></code></span></span>

 

原文链接

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值