具体如何使用,本章不关注。请自行百度。
关注核心方法 get() 和 set()
public class ThreadLocal<T> { //放 public void set(T value) { Thread t = Thread.currentThread(); ThreadLocalMap map = t.threadLocals; if (map != null) { map.set(this, value); } else { t.threadLocals = new ThreadLocalMap(this, firstValue);//key为当前的ThreadLocal变量,value为要放入的值 } } 原文:https://blog.csdn.net/lan861698789/article/details/81323757 //取 public T get() { Thread t = Thread.currentThread(); ThreadLocalMap map = t.threadLocals; if (map != null) { ThreadLocalMap.Entry e = map.getEntry(this); if (e != null) { return (T)e.value; } } return setInitialValue();//初始化为null } } |
分析:
1).实际的通过ThreadLocal创建的副本是存储在每个线程Thread自己的threadLocals中的;
在每个线程Thread内部有一个成员变量threadLocals,这个threadLocals就是用来存储实际的变量副本的,键值为当前ThreadLocal变量,value为变量副本(即T类型的变量)。
2).为何threadLocals的类型ThreadLocalMap的键值为ThreadLocal对象,因为每个线程中可有多个threadLocal变量,就像上面代码中的longLocal和stringLocal;
原文:https://blog.csdn.net/lan861698789/article/details/81323757
重点:
这个threadLocals就是用来存储实际的变量副本的,键值为当前ThreadLocal变量,value为变量副本(即T类型的变量)。
原文:https://blog.csdn.net/lan861698789/article/details/81323757
如果没有ThreadLocal,我们自己怎么实现呢?
1.需要Thread也为我们创建一个Map
2.然后Thread.currentThread()得到这个map,然后put一个自定义N个key进去。如keyA。
3.取的时候,同样拿到当前线程的map,然后get(keyA).