ThreadLocal就是Thread中的一个ThreadLocalMap类型的变量,用来存储线程的一些私有变量
    image.png
    使用场景:
    1.当使用一些线程不安全的工具类时可以使用,给每个线程分配一个工具类对象,这样就避免了线程共享一个工具类对象竞争导致的加锁消耗,也不需要频繁的去创建局部变量来解决线程不安全的问题
    2.一些线程的上下文信息(全局变量)可以存储在threadlocal里面,以免在方法的参数里面层层的传递(使用并发map也可以,并发map使用的cas和syn有性能消耗)

    ThreadLocalMap?
    他这个map底层是使用一个Entry数组来实现的,然后每个Entry就是一个ThreadLocal为key,value为Object类型的键值对
    (继承了弱引用),然后主要包括get,set和remove这几个方法
    get方法:先算出一个hash值然后和entry数组的长度做一个与运算找到对应的下标,然后这里可能会存在一个hash冲突的问题,那么他会把这个下标加一直到找到空的位置,get的时候也是先找到对应的下标,然后拿threadlocal和遍历到的entry去进行比对直到找到对应的value

    threadlocal能否共享?
    是可以的,子线程可以访问到父进程的inheritablethreadlocal
    public class Thread implements Runnable {
    ……
    if (inheritThreadLocals && parent.inheritableThreadLocals != null)
    this.inheritableThreadLocals=ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
    ……
    }
    Thread在初始化的时候会把父进程的inheritablethreadlocal设为自己的,然后他的子线程也可以使用他的

    ThreadLocal有什么问题?
    ThreadLocal有内存泄漏的隐患,特别是使用线程池的时候,由于创建ThreadLocal的线程一直存在,那么threadlocalmap里面的entry对象的value对象就会一直得不到回收,所以我们要在使用完这个threadlocal后在finally代码块里面手动remove

    key为什么要设计成弱引用?
    主要是为了减少内存泄漏的问题..
    我举个例子把,比如说我现在在一个类A里面定义了一个threadlocal对象,那么我这个类A的对象在使用期间对这个threadlocal是一个强引用,然后现在我使用了threadlocal的set添加了一个值,就在threadlocalmap里面创建了一个对threadlocal对象的弱引用,当这个类A的使用期间,threadlocal是一直存在强引用的,也就不会被gc干掉,当这个类A不再使用被gc干掉之后,threadlocal就只剩下了一个来自Threadlocalmap的entry的弱引用,就会直接被gc回收掉

    value为什么不设计成弱引用呢?