ThreadLocal 、ThreadLocalMap 与 Thread 的关系

ThreadLocal 、ThreadLocalMap 与 Thread 的关系

ThreadLocalMap 是一个类似HashMap的结构,但并不是Map的子类

ThreadLocalMapThreadLocal 的静态内部类
EntryThreadLocalMap 的静态内部类,也是 WeakReference(弱引用)的子类,
Entry是弱引用类型,所以当垃圾回收器进行回收时,无论内存是否足够,都会回收该对象的内存
ThreadLocalMap 中有一个属性:Entry[] table,用来存放key-value对,一个Entry实例对应 1份key-value
Thread类有一个 ThreadLocalMap 类型的属性:threadLocals,所以每一个 threadObj 都有1个自己独有的 ThreadLocalMap

ThreadLocal --> 内部类ThreadLocalMap --> 内部类Entry
ThreadLocalMap --> 属性:Entry[] table
Thread --> 属性:ThreadLocalMap threadLocals

1个threadObj --- 1ThreadLocalMap --- 1Entry[] --- 多个Entry --- 多份key-value数据 --- 多个key --- 1个key对应1个threadLocalObj

往ThreadLocalMap中设值  set
threadLocalObj.set(value) --> currentThread.threadLocals.set(threadLocalObj, value)
--> 根据 threadLocalObj 运算得到一个下标i --> table[i] = new Entry(threadLocalObj, value) = entryObj
最终 value 赋值给了entryObj 的 value 属性,并创建了一个指向key(也就是threadLocalObj)的弱引用,
这个弱引用与Entry的祖父类的属性关联,所以这个弱引用是被 entryObj 持有的

从ThreadLocalMap中取值  get
threadLocalObj.get() --> currentThread.threadLocals.getEntry(threadLocalObj) 
--> 根据 threadLocalObj 运算得到下标i --> 得到 table[i],拿 threadLocalObj 与 table[i] 持有的弱引用 比对 
--> 一致的话,table[i].value 就是所求的值

从ThreadLocalMap中删除键值  remove
threadLocalObj.remove() --> currentThread.threadLocals.remove(threadLocalObj) -->  根据 threadLocalObj 运算得到下标i
--> tab[i].clear --> 把tab[i]持有的弱引用赋值为null,即是把键值对的key设置为null
里面还有个expungeStaleEntry方法,不仅会把threadLocalObj对应的value擦除,
而且ThreadLocalMap中所有过时的key-value对都会擦除

1个线程 -- 对应一个ThreadLocalMap -- 对应多个键值对 -- 每个键值对对应1个threadLocalObj
所以如果要往ThreadLocalMap中存放多个键值对,那么就要创建多个 threadLocalObj

key-value对最终存放在 ThreadLocalMapEntry数组中

假设有a,b两个请求 --- 对应t1,t2两个线程 --- 对应ThreadLocalMap1ThreadLocalMap2
如果要往ThreadLocalMap中保存两个值value1和value2,那么则需要两个 threadLocalObj 作为key,
ThreadLocalMap1中的数据:threadLocalObj1:value1-t1  threadLocalObj2:value2-t1
ThreadLocalMap2中的数据:threadLocalObj1:value1-t2  threadLocalObj2:value2-t2

ThreadLocalMap 的生命周期:

ThreadLocalMap实例 随着 threadObj 第一次调用 threadLocalObj.set(value) 、threadLocalObj.get()时诞生,随着 threadObj 销毁而销毁。

threadLocalObj 直接关系到 key-value对 在 ThreadLocalMap 中的存放位置
因为每个线程都有自己的 ThreadLocalMap,所以使用同一个 threadLocalObj 并不会影响它们设值和取值
比如下面,ThreadLocal 是单例的,但 ThreadLocalMap 不是

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值