资料:
(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原理图: