• 玩转ThreadLocal


    ThreadLocal 是啥?  有什么作用?怎么玩? 底层如何实现?

    听说过ThreadLocal内存泄漏吗?  为啥?

    ThreadLocal key为啥设计成弱引用呢?

    三步走玩转ThreadLocal

    1.ThreadLocal详解

    是啥: ThreadLocal专门为线程服务,为线程提供一个单独的存储数据,对其他线程不可见,目的就是实现线程间资源的隔离。

    基本操作:

    set() 通过threadLocal向当前线程中存一个线程私有的值 "赵二"

    get() 通过threadLocal获取当前线程私有的值

    remove() 干掉线程中的当前thraedLocal及值

    玩起来:

    通过threadLocal,主线程set一个"赵二",AAA线程set一个"张三", BBB线程先set一个"李四" 后set一个"王五"

    观察得出结论,

    用同一个ThreadLocal  不同的线程set值互不影响,同一个线程set值会覆盖

    可以猜测threadLocal这个对象 更像是一个"标识",而不具备存储数据,具体的数据应该是存到了线程当中。

    底层实现:

    根据表现出来的性质大概也能猜到,每个线程应该会有一个存储threadLocal的地方,根据不同的threadLocal标识能获取到不同数据

    答案就在这里,Thread类中的182行,

    ThreadLocal.ThreadLocalMap threadLocals = null;

    ThreadLocalMap是ThreadLocal的一个静态内部类

    这一看 好家伙 这玩意这么像HashMap

    其内部又套娃静态内部类Entry,但是这个Entry继承了弱引用这个之后再说

    Entry的key就是ThreadLocal,value就是具体的值,ThreadLocalMap内部存的就是一个Entry数组

    画个图就清楚了,

    每个线程Thread中有一个ThreadLocalMap

    ThreadLocalMap中存的是Entry数组,key为ThreadLocal,value为具体的值

    在看看常用方法就更简单了

    获取到当前线程的ThreadLocalMap,把<ThreadLocal,value>存进去

    获取到当前线程的ThreadLocalMap,找到ThreadLocal对应的Entry,返value

    2.听说过ThreadLocal内存泄漏吗?

    所谓内存泄漏可以这么理解,有的对象明明没有引用了 不需要了,但是内存中干不掉,造成内存浪费

    为啥会这样呢,

    举个实例,

    线程AAA通过threadLocal  set"张三"到ThreadLocalMap,

    等AAA使用完了threadLocal,不需要他了,但是threadLocal并不会被gc回收掉 包括他的value值,

    因为threadLocal此时正作为一个Entry的key,被threadLocalMap引用,

    而threadLocalMap属于Thread的全局变量,生命周期与Thread相同,

    也就是说Thread不销毁,ThreadLocalMap就不会回收,其中的Entry不会回收,Entry不会回收 造成内存泄漏

    (这里假设的threadLocal是普通引用,而实际是弱引用下面再说)

    OK,那咋整呢,用完ThreadLocal及时把引用它的Entry干掉呗

    threadLocal.remove();

    或者干脆点 让线程销毁,一切都over

    3.弱引用问题

    会经常听到有说内存泄漏是因为ThreadLocal是弱引用造成的,

    因为ThreadLocal是弱引用, 弱引用任一次GC都会把他回收,那么Entry的key就为null了,Entry就永远访问不到了,造成内存泄漏

    我觉得这样说也对也不对,

    内存泄漏主要原因是Entry干不掉,因为他被ThreadLocalMap牢牢地把握住了,只能手动把他remove掉,

    弱引用的话只是帮忙把Entry的key干掉,而ThreadLocal有一层保护机制,set()或者get()时,如果找出来的key为null,则会帮忙把Entry干掉,帮忙避免一下内存泄漏

    so 用完ThreadLocal请及时remove() !

  • 相关阅读:
    Wampserver主机服务配置方法
    工作记录
    Shell教程
    简单教程
    java笔记
    四轴飞行器
    ace文档
    马尔科夫模型参考
    电子书搜索
    免费电子书
  • 原文地址:https://www.cnblogs.com/ttaall/p/15080595.html
Copyright © 2020-2023  润新知