ThreadLocal

https://www.cnblogs.com/fsmly/p/11020641.html

 

https://www.jianshu.com/p/3c5d7f09dfbd

 

https://juejin.cn/post/6893490343661174797#heading-7

 

https://zhuanlan.zhihu.com/p/192997550

 

ThreadLocal 应用场景

ThreadLocal 的特性也导致了应用场景比较广泛,主要的应用场景如下:

线程间数据隔离,各线程的 ThreadLocal 互不影响
方便同一个线程使用某一对象,避免不必要的参数传递
全链路追踪中的 traceId 或者流程引擎中上下文的传递一般采用 ThreadLocal
Spring 事务管理器采用了 ThreadLocal
Spring MVC 的 RequestContextHolder 的实现使用了 ThreadLocal

 

ThreadLocal 是如何实现线程隔离的呢?

ThreadLocal 是如何做到线程数据隔离,前面源码分析 ThreadLocal 的 set 方法已经分析过,这里我们再总结一下:

ThreadLocal之所以能达到变量的线程隔离,其实就是每个线程都有一个自己的ThreadLocalMap对象来存储同一个threadLocal实例set的值,而取值的时候也是根据同一个threadLocal实例去自己的ThreadLocalMap里面找,自然就互不影响了,从而达到线程隔离的目的。

 

 

Java的ThreadLocal,如果保障弱引用的Key使用后GC?

https://www.zhihu.com/question/338650108

https://www.cnblogs.com/huxipeng/p/9289191.html

关于ThreadLocal,网上有很多分析内存泄漏的文档,一直有个疑问,Entry的Key使用了弱引用,弱引用会在GC时被回收,那么就存在Key还未被使用,就给回收的情况。这样的话怎么保证添加Entry后,这个Entry被使用后,GC再去回收Key呢?

 

请注意这个key就是tl对象本身,而tl对象是你直接new出来的。只要你自己还持有tl对象的强引用,tl对象就不会被回收。而如果你丢失了tl对象的强引用,tl对象自然会被gc回收……其他任何正常Java对象不都这样吗?

 

有一个强引用和一个弱引用指向这个ThreadLocal实例

根据jvm的回收机制,你可以知道,因为有强引用指着它,它是绝对不会被回收的,那么它被回收只有一种状况

你那个强引用的变量,不想指向这个ThreadLocal实例了,他换了一个实例去指向,或者你直接给他变成null了

 

如何保障一直有强引用指向ThreadLocal对象来保障其不会被GC

定义成static final

ThreadLocal为什么建议用static修饰

1,static修饰的变量的生命周期
首先static修饰的变量是在类在加载时就分配地址了,在类卸载才会被回收,这一点请明确.

2,分析
ThreadLocal的原理是在Thread内部有一个ThreadLocalMap的集合对象,他的key是ThreadLocal,value就是你要存储的变量副本, 不同的线程他的ThreadLocalMap是隔离开的,如果变量ThreadLocal是非static的就会造成每次生成实例都要生成不同的ThreadLocal对象,虽然这样程序不会有什么异常,但是会浪费内存资源.造成内存泄漏.

所以建议ThreadLocal用static修饰

posted @ 2021-03-09 16:26  超轶绝尘  阅读(152)  评论(0编辑  收藏  举报