zoukankan      html  css  js  c++  java
  • Java并发--ThreadLocal

    ThreadLocal 用于存储线程私有的对象。

    查看 Thread 类的源码可以发现,每个 Thread 对象中都会有一个 ThreadLocalMap 的属性,它是一个 HashMap 结构, key 是 ThreadLoacl 对象, value 是该 ThreadLocal 存储的 Object。

    线程初始时,ThreadLocalMap 是空的,当我们需要为线程设置它的私有对象时,可以新建一个 ThreadLocal 对象,像这样:

    ThreadLocal<Object> threadLocal = new ThreadLocal<Object>();
    

    它的主要方法有:

    public T get() { }  
    public void set(T value) { }  
    public void remove() { }  
    protected T initialValue() { } 
    

    然后可以通过 set 方法放进去一个对象,可以通过 get 方法获取对象。

    我们来看一张图就清晰了。

    ThreadLocal 和它的 Object 就是存在了该线程的 ThreadLocalMap 中,所以很明显是线程私有的。

    如果线程挂了,ThreadLocalMap 失去引用,就会被回收掉。

    • 弱引用问题

      ThreadLocalMap 中用到了弱引用,ThreadLocalMap 的 Entry 中 key 是 ThrealLocal 对象, value 是 ThrealLocal 对象所对应的 Object。如果出现这样的情况:程序中的 ThreadLocal 对象失去了强引用,但是 key 仍然持有对它的引用,如果这个引用是强引用,ThreadLocal 将永远不会被回收。因此这里设计者把 key 对 ThreadLocal 的引用设置为了弱引用。(个人认为这里是防止了ThreadLoacl对象无法回收导致的内存泄露,下小节讲的是Object对象产生的内存泄露)

    • 内存泄露问题

      如果线程一直活着,但是 ThreadLocal 因为一些操作导致失去了强引用,那么它就会被回收。那么将导致 ThreadLocalMap 中存在 <null, Object> 的键值对,即内存泄露了。

      所以在使用完 ThreadLocal 后,应该调用 remove 主动移除ThreadLocalMap 中的键值对。

    • 使用注意

      一般我们把 ThreadLocal 定义为 static(这是JDK的推荐),因为如果ThreadLocal 是实例属性,那么在线程中每创建一个这个类的实例,就也会新建一个 <ThreadLocal, Object>, 对于 Object 而言是存在冗余的,因此也造成了一定的浪费。

    *关于内存泄露这块感觉理解还不是很深,主要是没有结合实际生产案例。

  • 相关阅读:
    在Power BI报表和仪表板中显示刷新日期时间
    微软Power BI 每月功能更新系列——12月Power BI 新功能学习
    在Microsoft Power BI中创建地图的10种方法
    您应该将报表从Excel转换为Power BI的8个原因
    OBS录制全屏游戏的方法(超好录屏)
    关于Adobe Premiere Pro视音频不同步的解决方法
    Npcap:Nmap项目里一个为Windows而生的嗅探库 Npcap: Nmap Project's packet sniffing library for Windows
    关于被malloc分配内存的指针
    VS2017 高级使用方法
    Npcap环境配置(Winpcap后继者) pcap的一种
  • 原文地址:https://www.cnblogs.com/cpcpp/p/15212445.html
Copyright © 2011-2022 走看看