美文网首页
Threadlocal本质原理

Threadlocal本质原理

作者: tracy_668 | 来源:发表于2018-03-31 16:27 被阅读7次

   Threadlocal的作用是提供线程内的局部变量,这种变量在线程的生命周期内起作用,也就是在一个线程的不同方法里要被使用到,使用ThreadLocal来存储这些变量的目的就是为了减少同一个线程内多个方法之间一些公共变量的传来传去,实现当需要使用时直接从ThreadLocal获取。如果让我们自己去设计ThreadLocal来达到这种效果,怎么做?

每个ThreadLocal类创建一个Map,然后用线程的id作为map的key,要传递的对象作为map的value?这样就能达到各个线程的值隔离的效果。早期jdk中的ThreadLocal确实这样设计,但后面jdk进行了优化。

ThreadLocal的构造函数

构造函数啥都没做。它用initialValue来设置ThreadLocal的初始值,

该函数在调用get函数时会第一次调用时被调用

get方法的流程:

1:首先获取当前线程;

2:根据当前线程获取一个map;

3:如果获取的map不为空,则在该map中以Threadlocal对象引用作为key来在map中获取对应的value e 否则转到5 ;

4:如果e不为null,返回e.val ;

5:  Map 为null或者e为空,则通过initialvalue函数获取初始值value,然后用ThreadLocal的引用和value作为firstkey和firstvalue创建一个新的map。

这里的map是ThreadLocal的静态内部类ThreadLocalMap. 每个Thread维护一个 ThreadLocalMap,这个映射表的key是ThreadLocal实例本身,value是真正要存储的对象。

这种设计相比早期jdk中那样设计的好处是:

     1:每个map的Entry的数量变少了,之前是 Thread的数量,现在是ThreadLocal的数量,之前对于一个线程内的多个变量需要多个map,现在一个线程的多个变量对应多个threadlocal。之前一个map对应多个线程,现在一个map只对应一个线程,这样更合理,一个线程里的所有变量放在一个map,而不应该分散在不同的map!

    2: 当Thread销毁之后对应的ThreadLocalMap也随之销毁了,而不必显示地释放,能避免内存泄漏问题。

ThreadLocal进阶

需要注意的是,ThreadLocalMap是使用ThreadLocal的弱引用作为key的,如果一个 ThreadLocal没有外部强引用引用它,那么系统gc时,这个ThreadLocal必定会被回收,这样 ThreadLocalMap中会出现key为null的Entry,当前线程迟迟不结束的话,这些key为null的 entry的value就会一直存在强引用,而无法被回收。

ThreadLocalMap的getEntry函数的流程为:

1: 根据ThreadLocal的threadlocalhashcode获取直接索引位置,得到entry e,如果e不为null并且可以相同则直接返回e

2: 如果e为null或者key不一致,则向下一个位置查询,如果下一个位置的key和当前需要查询的key相等,则返回对应的entry,如果key为null,则擦除该位置的entry,继续向下一个位置查询。

在这个过程中遇到key为null的entry都会被擦除,entry内的value也就没有强引用了。将这些key为null的entry擦除有效防止了内存泄漏。但是这需要调用getEntry和set函数,通常很多情况下需要使用者手动调用ThreadLocal的remove函数,remove函数会清除对应的value。jdk建议将ThreadLocal变量定义为private static 让其一直存在着强引用,ThreadLocal也就不会被回收 。

那么为什么要使用弱引用呢??而不是直接使用强引用?

key如果使用强引用: 引用的threadlocal对象不再使用了,但是threadlocalmap还持有强引用,如果没有手动删除,threadlocal不会被回收,导致entry内存泄漏。ThreadLocalMap的什么周期与Thread一样长,如果都没有手动删除对应的key,都会导致内存泄漏,使用弱引用可以多一层保障,并且弱引用ThreadLocal不会内存泄漏,对应的value会在ThreadlocalMap调用set、get、remove方法时被清除。

相关文章

网友评论

      本文标题:Threadlocal本质原理

      本文链接:https://www.haomeiwen.com/subject/vfpgcftx.html