一、ThreadLocal就是同一线程内 ,线程安全的数据共享 里面存的数据在线程销毁后,会自动释放
内部大致结构

ThreadLocal里面有内部类ThreadLocalMap , ThreadLocalMap里面又有内部类Entry
二、set和get方法源码
1.set方法
public void set(T value) {
* 1.获取当前线程
* Thread t = Thread.currentThread();
* 2.获取到线程内部类的Map(Map里面还有Entry内部类)
* ThreadLocalMap map = getMap(t);
* 3.这里判断是否是null
* if (map != null)
* 4.不是就进入,这个this就是当前的线程 value就是放得东西
* 5.这里面只能存储一对,重复的话,会直接替换
* map.set(this, value);
* else
* 3.1.如果是null那就直接获取t线程的Map,同时放入value
* createMap(t, value);
* }
上面是源码及解析 ,下面我们debug一下
在ThreadLocal对象内部会有个threadLocals,里面有table 用于存放数据
在还未执行set方法时threadLocals 是null

3.这个是传入对象后

因为底层源码是让entry只能存储一层所以,如果传入多次数据,前面的都会被后面替换
* if (map != null)
就是因为下面这句代码,底层是Entry的机制key一样Vlalue不同就用后面的替换前面的
* map.set(this, value);

如果多个线程都进行存储,会放在同一个threadLocals的table里

如上图所示,在里面排序是根据哈希算法进行排序的(不懂的可以去学习Entry)
get方法源码
public T get() {
// 获取当前线程
// Thread t = Thread.currentThread();
// 2.获取Map
// ThreadLocalMap map = getMap(t);
// 3.map不是null就进去
// if (map != null) {
// 4.根据调用线程 来获取对应的entry , this就是(调用方法的线程)
// ThreadLocalMap.Entry e = map.getEntry(this);
// if (e != null) {
//
// @SuppressWarnings("unchecked")
// 5.返回当前当前threadLocal关联的value
// T result = (T)e.value;
// return result;
// }
// }
// 3.如果是null就初始化
// return setInitialValue();
// }
基本上和set大差不差,其中有一点需要注意,就是有多个线程都存储了值如何保证 取出来的和存的是一样的
其实map.getEntry(this);底层会有一套比较,具体看下图

ThreadLocal源码到这里就差不多了,但是其中底层this还涉及弱引用,我目前还没有学,有兴趣的大佬可以去了解下,或者我说的不对的大佬也可以在评论区指正