ThreadLocal 源码解析及实战应用

2023-02-23 0 487

原副标题:ThreadLocal 源代码导出及两栖作战应用领域

译者 | 天猫云开发人员-天猫仓储 闫鹏勃

1 甚么是 ThreadLocal?

ThreadLocal 是两个有关建立缓存局部表达式的类。

一般来说情况下,他们建立的表达式是能被任何人两个缓存出访并修正的。而采用 ThreadLocal 建立的表达式根本无法被现阶段缓存出访,其它缓存则无法出访和修正。ThreadLocal 在结构设计Hathras是为化解mammalian难题而提供更多一类计划,每一缓存保护这份他们的统计数据,达至缓存隔绝的效用。

2 有甚么促进作用?2.1 set once,get everywhere

在那时的控制系统结构设计中,其间端分立已基本上正式成为恒常,分立后

在前述的控制系统户重要信息都能采用 ThreadLocal 的 get 方式 (触发器流程中 ThreadLocal 是不可信的)

2.2 缓存安全可信,内部空间换天数

在 Spring 的 Web 工程项目中,他们一般来说会将销售业务分成 Controller 层,Service 层,Dao 层, 他们都晓得 @Autowired 注释预设采用科枫商业模式,所以相同允诺缓存进去后,虽然 Dao 层采用科枫,所以负责管理资料库相连的 Connection 也多于两个, 假如每一允诺缓存都去相连资料库,所以就会导致缓存不安全可信的难题,Spring 是怎样化解那个难题的呢?

在 Spring 工程项目中 Dao 层中装配的 Connection 肯定是线接后存入 ThreadLocal 中,如此一来,每两个允诺缓存都保存有这份 他们的 Connection。于是便化解了缓存安全可信难题

3 ThreadLocal 两栖作战应用领域3.1 ehr 中的采用

在登录拦截器中将用户重要信息写入,后续采用时方便取值

ThreadLocal 源码解析及实战应用

3.2 分页插件 PageHelper 中的应用领域

ThreadLocal 源码解析及实战应用

ThreadLocal 源码解析及实战应用

3.3 AopContext

ThreadLocal 源码解析及实战应用

4 源代码解读

你是否有这样的疑惑?为甚么能直接拿到?对象存放在哪里?存在甚么难题?

4.1 get 方式

用 setInitialValue 方式返回初始值,并保存到新建立的 ThreadLocalMap 中。

ThreadLocal 源码解析及实战应用

4.2 set 方式

al 作为 key;否则建立两个 ThreadLocalMap 并给到现阶段缓存,然后保存 value。

ThreadLocalMap 相当于两个 HashMap,是真正保存值的地方

map 的 set,如果 map 为空,则建立两个

ThreadLocal 源码解析及实战应用

4.3 initialValue 方式

initialValue 是 ThreadLocal 的初始值,预设返回 null,子类能重写改方式,用于设置 ThreadLocal 的初始值。

4.4 remove 方式

ThreadLocal 还有两个 remove 方式,用来移除现阶段 ThreadLocal 对应的值。同样也是同过现阶段缓存的 ThreadLocalMap 来移除相应的值。

getMap 拿到了甚么?

LocalMap 为 null,则会建立两个 ThreadLocalMap,并给到现阶段缓存

此处 t 是 Thread,直接能 “点” 拿到那个 map

每一 Thread 对象内部都保护了两个 ThreadLocalMap 这样两个 ThreadLocal 的 Map,能存放若干个 ThreadLocal

ThreadLocal 源码解析及实战应用

LocalMap 来完成操作。每一缓存的 ThreadLocalMap 是属于缓存他们的,ThreadLocalMap 中保护的值也是属于缓存他们的。这就保证了 ThreadLocal 类型的表达式在每个缓存中是独立的,在多缓存环境下不会相互影响。

5 采用注意事项

1)有可能导致内存泄漏,采用完毕后,需要 remove

在 ThreadLocalMap 的 set ,get 和 remove 方式中,都有清除无效 Entry 的操作,这样做是为了降低内存泄漏发生的可能。

Entry 中的 key 采用了弱引用的方式,这样做是为了降低内存泄漏发生的概率,但不能完全避免内存泄漏。

ThreadLocal 源码解析及实战应用

假设 Entry 的 key 没有采用弱引用的方式,而是采用了强引用:虽然 ThreadLocalMap 的生命周期和现阶段缓存一样长,所以当引用 ThreadLocal 的对象被回收后,虽然 ThreadLocalMap 还持有 ThreadLocal 和对应 value 的强引用,ThreadLocal 和对应的 value 是不会被回收的,这就导致了内存泄漏。所以 Entry 以弱引用的方式避免了 ThreadLocal 没有被回收而导致的内存泄漏,但是此时 value 仍然是无法回收的,依然会导致内存泄漏。

ThreadLocalMap 已经考虑到这种情况,并且有一些防护措施:在调用 ThreadLocal 的 get ,set 和 remove 的时候都会清除现阶段缓存 ThreadLocalMap 中所有 key 为 null 的 value。这样能降低内存泄漏发生的概率。所以他们在采用 ThreadLocal 的时候,每次用完 ThreadLocal 都调用 remove 方式,清除统计数据,防止内存泄漏。

2)采用缓存池时,父子缓存传递慎用,因为初始化时机为缓存建立时

ThreadLocal 源码解析及实战应用

3)针对 2 有甚么计划能化解?

TransmittableThreadLocal

源代码地址:https://github.com/alibaba/transmittable-thread-local

详解:https://www.jianshu.com/p/e0774f965aa3

END

聊聊企业开源的底层逻辑

这里有最新开源资讯、软件更新、技术干货等内容

点这里 ↓↓↓ 记得 关注✔ 标星⭐ 哦~

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务