ThreadLocal全面解析
1、什么是ThreadLocal
ThreadLocal提供线程内的局部变量,不同的线程之间不会相互干扰,这种变量在线程的生命周期内起作用,减少同一个线程内或组件之间一些公共变量传递的复杂度。
2、如何使用
ThreadLocal的方法主要就是set(),get(),remove(),没啥好说的。
看一下线程不隔离导致读取了本不该属于它的数据。

当使用ThreadLocal将变量与当前线程绑定:

3、实现原理
3.1 set()
set方法也就是把数据放入ThreadLocalMap中

而ThreadLocalMap的实现是通过Entry数组


可以看出,当前ThreadLocal的引用k被传递给WeakReference的构造函数,所以ThreadLocalMap中的key为ThreadLocal的弱引用。当一个线程调用ThreadLocal的set方法设置变量的时候,当前线程的ThreadLocalMap就会存放一个记录,这个记录的key值为ThreadLocal的弱引用,value就是通过set设置的值。如果当前线程一直存在且没有调用该ThreadLocal的remove方法,如果这个时候别的地方还有对ThreadLocal的引用,那么当前线程中的ThreadLocalMap中会存在对ThreadLocal变量的引用和value对象的引用,是不会释放的,就会造成内存泄漏。
3.2 get()
在get方法的实现中,首先获取当前调用者线程,如果当前线程的threadLocals不为null,就直接返回当前线程绑定的本地变量值,否则执行setInitialValue方法初始化threadLocals变量。

在setInitialValue方法中,类似于set方法的实现,都是判断当前线程的threadLocals变量是否为null,是则添加本地变量(这个时候由于是初始化,所以添加的值为null),否则创建threadLocals变量,同样添加的值为null。

3.3 remove()
remove方法判断该当前线程对应的threadLocals变量是否为null,不为null就直接删除当前线程中指定的threadLocals变量。

4、扩展
- 强引用:如果一个对象具有强引用,它就不会被垃圾回收器回收。即使当前内存空间不足,JVM也不会回收它,而是抛出 OutOfMemoryError 错误,使程序异常终止。如果想中断强引用和某个对象之间的关联,可以显式地将引用赋值为null,这样一来的话,JVM在合适的时间就会回收该对象 ;
- 软引用:在使用软引用时,如果内存的空间足够,软引用指向的对象就能继续被使用,而不会被垃圾回收器回收,只有在内存不足时,软引用指向的对象才会被垃圾回收器回收;
- 弱引用:具有弱引用的对象拥有的生命周期更短暂。因为当 JVM 进行垃圾回收,一旦发现弱引用对象,无论当前内存空间是否充足,都会将弱引用指向的对象回收。不过由于垃圾回收器是一个优先级较低的线程,所以并不一定能迅速发现弱引用对象 。
- 虚引用:顾名思义,就是形同虚设,如果一个对象仅持有虚引用,那么它相当于没有引用,在任何时候都可能被垃圾回收器回收。
- 点赞
- 收藏
- 关注作者
评论(0)