美文网首页
ThreadLocal相关概念

ThreadLocal相关概念

作者: 一生逍遥一生 | 来源:发表于2019-05-29 17:01 被阅读0次

    ThreadLocal提供线程内部变量。ThreadLocal创建的变量只能被当前线程访问,其他线程则无法访问和修改。

    当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。

    ThreadLocalMap是一个自定义的HashMap结构,只适用于维护线程本地值。
    为了帮助处理非常大切长期使用的用法,hash table entry使用若引用作为key。
    但是,因为没有引用队列,因此只有表开始空间不足时才能保证删除过时条目。

    ThreadLocalMap使用若引用的原因在于,当没有强引用指向ThreadLocal变量时,它可被回收这样避免
    ThreadLocal不能被回收而造成的内存泄漏的问题。但是,这里又可能出现另外一种内存泄漏的问题。
    ThreadLocalMap 维护 ThreadLocal 变量与具体实例的映射,
    当 ThreadLocal 变量被回收后,该映射的键变为 null,该 Entry 无法被移除。
    从而使得实例被该 Entry 引用而无法被回收造成内存泄漏。

    ThreadLocalMap的set方法,会将建为null的entry的值设置为null,从而使得该值可被回收。

    Thread类中有一个threadLocals和inheritableThreadLocals,它们都是ThreadLocalMap类型的变量,
    而ThreadLocalMap是一个定制化的HashMap,在默认情况下,每个线程中的这两个变量都为null,
    只有当前线程第一次调用ThreadLocal的set或者get方法才会创建它们。ThreadLocal类型的本地变量存放在具体的线程内存空间中。

    threadlocals是一个HashMap结构,其中key就是当前ThreadLocal的实例对象引用,value是通过set方法传递的值。

    InheritableThreadLocal继承自ThreadLocal,可以访问在父线程中设置的本地变量。

    InheritableThreadLocal的世界里,变量inheritableThreadLocals替代了threadlocals。
    InheritableThreadLocal通过重写方法将本地变量保存到了具体线程的inheritableThreadLocals变量里面。
    当父线程创建子线程时,构造函数会把父线程中inheritableThreadLocals变量里面的本地变量复制一份保存到子线程的inheritableThreadLocals变量里面。

    ThreadLocal用来保存线程上下文信息,在任意需要的地方可以获取;线程安全的,不适用于共享对象的更新问题。

    一个ThreadLocal只能存储一个Object对象,如果需要存储多个Object对象那么就需要多个ThreadLocal。

    弱引用也是用来描述非必需对象的,当JVM进行垃圾回收时,无论内存是否充足,该对象仅仅被弱引用关联,那么就会被回收。

    当仅仅只有ThreadLocalMap中的Entry的key指向ThreadLocal的时候,ThreadLocal会进行回收的!!!

    ThreadLocal定义为static还有一个好处就是,由于ThreadLocal有强引用在,那么在ThreadLocalMap里对应的Entry的键会永远存在,那么执行remove的时候就可以正确进行定位到并且删除!!!

    Netty的核心设计就是将原生的Map结构替换为数组结构。每个FastThreadLocal对象生成一个全局唯一的index,并使用InternalThreadLocalMap中的数组通过index寻址,这样就直接解决了哈希冲突的问题。

    小结

    1:ThreadLocal是线程执行时的上下文,用于存放线程局部变量。它不能解决并发情况下数据共享的问题
    2:ThreadLocal是以ThreadLocal对象本身作为key的,不是线程(Thread)对象
    3:ThreadLocal存在内存泄露的风险,要养成用完即删的习惯
    4:ThreadLocal使用散列定位数据存储坐标,如果发生碰撞,使用线性探测重新定位,这在高并发场景下会影响一点性能。改善方法如netty的FastThreadLocal,使用固定坐标,以空间换时间,后面会分析FastThreadLocal实现。

    参考文献

    https://www.kancloud.cn/ssj234/netty-source/438383
    https://blog.verysu.com/mobile/article/403
    https://blog.csdn.net/zhousenshan/article/details/82942145
    https://www.cnblogs.com/stevenczp/p/7667719.html
    https://segmentfault.com/a/1190000012926809
    并发五: 透过源码彻底理解ThreadLocal

    相关文章

      网友评论

          本文标题:ThreadLocal相关概念

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