ThreadLocalMap原理

Posted wu-1393180819

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ThreadLocalMap原理相关的知识,希望对你有一定的参考价值。

资料:

(1)通过ThreadLocal为每个线程提供单独的副本:

https://blog.csdn.net/lovelovelovelovelo/article/details/72835385

(2)ThreadLocal设计模式:

https://blog.csdn.net/hua286306956/article/details/8660268

Thread类:

public class Thread implements Runnable{
    /**声明ThreadLocalMap类对象,它可以存储多个ThreadLocal静态常量的哈希标记
     * 而一个ThreadLocal静态常量可以维护一个线程内变量
     * 即一个ThreadLocalMap类对象可以存储多个线程内变量而这些变量的key就是它们各自的维护者:ThreadLocal静态常量的哈希标记
     * **/
    ThreadLocal.ThreadLocalMap threadLocals =null;
    /**返回对当前执行的线程对象的引用,“native”表示该方法是由c语言编写的底层方法*/
    public static native Thread currentThread();
    @Override
    public void run() {
        //省略
    }
}

ThreadLocal类:

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
/**原理,类似于访问者模式,ThreadLocal是访问者,Thread是被访问者。
 * ThreadLocal访问的是Thread的局部变量ThreadLocalMap
 * 当使用ThreadLocal维护变量时,ThreadLocal为每个【使用该变量的线程】提供独立的变量副本,
 * 所以每个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本.
**/
public class ThreadLocal<T> {
    //线程的内部变量ThreadLocalMap对象    对ThreadLocal对象所维护的  线程内变量   的一种哈希标记
    private final int threadLocalHashCode = new AtomicInteger().getAndAdd(0x61c88647);
    //定义ThreadLocalMap内部类
    static class ThreadLocalMap{
        //源码逻辑是一种哈希映射,这里暂时用Map替代
        //以当前ThreadLocal对象的标记 作为key
        Map<Integer,Object> m = new HashMap<Integer,Object>();
        public ThreadLocalMap(ThreadLocal threadLocal, Object firstObj) {
            //--省略
        }
        void set(ThreadLocal threadLocal, Object value){
            m.put(threadLocal.threadLocalHashCode, value);
        }
        Object get(ThreadLocal threadLocal){
            return m.get(threadLocal.threadLocalHashCode);
        }
        void remove(){}
    }
    //访问的是Thread的局部变量ThreadLocalMap,并为其注入值
    public void set(T t){
          //获取当前线程,然后获取到当前线程里面的ThreadLocalMap引用
          ThreadLocalMap map = Thread.currentThread().threadLocals;
          //以当前ThreadLocal对象为参数
          map.set(this,t);
    }
    
    //访问的是Thread的局部变量ThreadLocalMap,并获取其值
    public T get(){
          ThreadLocalMap map = Thread.currentThread().threadLocals;
          if(null!=map){
              return  (T) map.get(this);
          }
          //如果为空,则初始化(创建并设置对象副本)
          return setInitialValue();
    }
    
    private T setInitialValue(){
         Thread thread = Thread.currentThread();
         ThreadLocalMap map = thread.threadLocals;
         if (map != null)
             map.set(this, null);
         else
             map = new ThreadLocalMap(this, null);
         return null;
    }
}

 

ThreadLocalMap原理图:

技术分享图片

 

以上是关于ThreadLocalMap原理的主要内容,如果未能解决你的问题,请参考以下文章

ThreadLocal

分析Threadlocal内部实现原理,并解决Threadlocal的ThreadLocalMap的hash冲突与内存泄露

ThreadLocal的正确使用与原理

ThreadLocal原理

ThreadLocal 详解

ThreadLocal 工作原理部分源码分析