zoukankan      html  css  js  c++  java
  • 并发容器之ThreadLocal详解

    一、定义

    https://baijiahao.baidu.com/s?id=1653790035315010634&wfr=spider&for=pc

    threadlocal而是一个线程内部的存储类,可以在指定线程内存储数据,数据存储以后,只有指定线程可以得到存储数据

    当使用ThreadLocal维护变量的时候 为每一个使用该变量的线程提供一个独立的变量副本,即每个线程内部都会有一个该变量,这样同时多个线程访问该变量并不会彼此相互影响,因此他们使用的都是自己从内存中拷贝过来的变量的副本, 这样就不存在线程安全问题,也不会影响程序的执行性能。

    但是要注意,虽然ThreadLocal能够解决上面说的问题,但是由于在每个线程中都创建了副本,所以要考虑它对资源的消耗,比如内存的占用会比不使用ThreadLocal要大。

    举例:

    ThreadLocal<String> localName = new ThreadLocal();
    localName.set("小狼");
    String name = localName.get();

    在线程1中初始化了一个ThreadLocal对象localName,并通过set方法,保存了一个值小狼,同时在线程1中通过localName.get()可以拿到之前设置的值,但是如果在线程2中,拿到的将是一个null。

    在ThreadLoalMap中,也是初始化一个大小16的Entry数组,Entry对象用来保存每一个key-value键值对,只不过这里的key永远都是ThreadLocal对象,通过ThreadLocal对象的set方法,结果把ThreadLocal对象自己当做key,放进了ThreadLoalMap中。

    二、ThreadLocal的工作原理

    1.每个Thread实例内部都有一个ThreadLocalMap,ThreadLocalMap是一种Map,它的key是ThreadLocal,value是Object。

    2. 存数据 是往当前线程的ThreadLocalMap中存入数据,其key是当前ThreadLocal对象,value是set方法中传入的值。

    3.使用数据时,以当前ThreadLocal为key,从当前线程的ThreadLocalMap中取出数据。

    三、ThreadLocal内存泄漏分析与解决方案

    ThreadLocalMap 中使用的 key 为 ThreadLocal 的弱引用,而 value 是强引用。所以,如果 ThreadLocal 没有被外部强引用的情况下,在垃圾回收的时候,key 会被清理掉,而 value 不会被清理掉。这样一来,ThreadLocalMap 中就会出现key为null的Entry。假如我们不做任何措施的话,value 永远无法被GC 回收,这个时候就可能会产生内存泄露。ThreadLocalMap实现中已经考虑了这种情况,在调用 set()、get()、remove() 方法的时候,会清理掉 key 为 null 的记录。使用完 ThreadLocal方法后 最好手动调用remove()方法

    造成内存泄漏的原因:

    1.key为弱引用,gc之后key为null,导致value无法被获取到
    2.ThreadLocalMap的生命周期与Thread相同,导致内存泄漏一直存在

    解决方案: 

    每次使用完ThreadLocal,都调用它的remove()方法,清除数据。

    通过下图进行分析:

    ThreadLocal本身并不存储值,它只是作为一个key来让线程从ThreadLocalMap获取value

     现在,我们假设ThreadLocal完成了自己的使命,与ThreadLocalRef断开了引用关系。此时内存图变成了这样。

     系统GC发生时,由于Heap中的ThreadLocal只有来自key的弱引用,因此ThreadLocal内存会被回收到。

     到这里,value被留在了Heap中,而我们没办法通过引用访问它。value这块内存将会持续到线程结束。造成内存泄漏。

  • 相关阅读:
    vue-cli脚手架工具构建&初始化vue项目
    2020/05/17 Github加速-DNS配置
    同时将本地git仓库提交到gitee和github
    git远程仓库在本地看不到&push 到远程仓库失败的解决方案
    stylus的使用-变量和函数
    webpack使用4-HRM热替换&SourceMap&解析es语法
    webpack使用3-plugin插件的使用
    webpack使用2-常用的几个loader的使用
    webpack基本使用
    spring框架里面的注入?
  • 原文地址:https://www.cnblogs.com/jingpeng77/p/12881743.html
Copyright © 2011-2022 走看看