补充:关于ThreadLocal,请看这篇文章关于ThreadLocal内存泄漏的问题_小星向上的博客-CSDN博客
引言:最近在查看shiro登录成功后,获取当前登录人的信息时发现了里面使用了InheritableThreadLocal,,但是我好奇,如果我在里面新建了一个线程,那怎么获取登录人的信息呢,结果发现shiro源码里面使用了InheritableThreadLocal
关于InheritableThreadLocal
我们查看InheritableThreadLocal源码上面的注释,
可以大概得出该类的作用是: ⭐自己总结的,有错的话麻烦提出
该类继承ThreaLocal,肯定是在ThreaLocal上面进行扩展,
创建子线程时,子线程将接收父线程InheritableThreadLocal变量里面的值。
说白了就是:当我们使用InheritableThreadLocal给线程设置值的时候,在创建一个线程,该线程也会拥有InheritableThreadLocal里面的值
代码演示
主要用于父子线程间ThreadLocal变量的传递
通过下图可以发现,我们使用InheritableThreadLocal时, 是可以传递的,也就是新创建的线程也能够获取到父线程的InheritableThreadLocal变量的值
代码分析:
1.首先我们知道
InheritableThreadLocal.set方法,是调用的ThreadLocal的set方法,他们是继承关系,InheritableThreadLocal继承ThreadLocal
2.set方法
ThreadLocal.set方法,就是 获取当前线程的 threadLocals变量 (ThreadLocalMap类型) , 给该变量put值,key为ThreadLocal对象本身
线程的inheritableThreadLocals变量
源码分析:
我开始思考了很久是怎么实现的?? 也没有想出来,最后还是查看Thread里面的源码得知实现原理
大致流程:
new Thread() -> 调用构造方法 -> 获取到当前线程 -> 拿到当前线程的inheritableThreadLocals变量 -> 赋值给新的线程
new Thread(()->{ System.out.println(String.format("thread 1 print:%s",local.get())); })
当我们创建Thread的时候,会调用下面的构造方法
构造方法里面 会获取到当前执行的线程 :parent
拿到当前线程的inheritableThreadLocals 变量,如果不为空,就把该变量的值赋值给我们新创建的线程, 实现了传递,这也就是为啥 我们新创建的线程也能够获取得到 ThreadLocal里面的值的原因
不得不说,还是很机智了,我开始想了很久也没有想到实现方法, 没想到源码里面是这样实现的,
也就是我进行new 线程的时候,其实是由一个线程来执行的,我就获取执行的线程的
inheritableThreadLocals值,如果不为空,就把值赋值给我new的线程,这样的话,new的线程对象里面也有该变量的值了,完成了threadLocal的传递