ThreadLocal原理及其内存泄漏

ThreadLocal通过为每个线程创建一个共享变量的副本来保证各个线程之间变量的访问和修改互不影响。

ThreadLocal存放的值是线程内共享的,线程间互斥的,主要用于线程内共享数据,避免通过参数传递。

ThreadLocal有四个方法:

initialValue:返回此线程局部变量的初始值。

get:返回此线程局部变量的当前线程副本的值。如果线程第一次调用该方法,则创建并初始化此副本。

set:将当前线程副本的值设置为指定值。

remove:移除此线程局部变量的值。

Thread内部有两个变量,threadLocals和inheritableThreadLocals

ThreadLocal内部有个静态内部类ThreadLocalMap,而在外部没办法获取到这个类,每次操纵都需要通过ThreadLocal。而这个map里面维护了一个数据结构为Entry的数组,key就是ThreadLocal,value就是ThreadLocal的value;,而且这个引用还是个弱引用;具体节点类型如下

所以当系统中存在多个线程的时候,具体的引用是这个样子的(手头画图工具太难用,手快一些,将就看吧):

首先最上面一条引用线路,threadLocal对象,这是个弱引用如果没有其他引用这个就会被回收。

但是,下面两条引用都是强引用,进行GC的时候进行标记,只要线程不消亡threadlocal还是可达的;

如果是不用线程池的话,这里随着线程的消亡,下面两个引用也就没了,GC就会回收掉该片区域,但是现住基本上线程都是在线程池里的,如果一个线程会一直活跃不会消亡,在这种情况下,如果在生命周期结束的时候没有去显式的的清理变量(在线程任务完成时调用ThreadLocal的remove方方法),那线程内部的引用会依然存在,虽然这时候threadlocal已经是null了,但是对应的value依然存在,这时候线程内部里的threadlocalmap里就会存在一个key为null的Entry,因为key是null,所有这块数据永远都不会被访问的,这就是内存泄漏了。

相关推荐
mldong1 小时前
一个 App,十三套后端:手机审批端 uni-jeeflow-app 开源了
java·架构
tqs_123452 小时前
MySQL RR隔离级别死锁|Gap间隙锁、临键锁,订单并发范围查询死锁根因方案
java
逆境不可逃3 小时前
Pi Agent 学习笔记:多个工具怎样并行执行
java
Flynt3 小时前
Java 27 升级实测:默认值动得比新特性多,有个老参数会让 JVM 直接起不来
java·jvm·后端
Bs_MoneyMagnet3 小时前
基于springboot+vue的个人健康管理系统的设计与实现 源码+文档
java·vue.js·spring boot·后端·vue3·springboot3·计算机毕业设计
星云API技术支持4 小时前
企业微信二次开发:群权限设置、成员管理与群资料维护的接口组合实践
java·前端·企业微信
niucloud-admin4 小时前
JAVA V6 多商户商城 开发文档——job 计划任务开发
java·python·github
海宇AI5 小时前
零信任架构实战:基于海宇柠檬查出险-登记证构建自动化车抵贷核保网关
java·人工智能·架构·自动化
cfm_29147 小时前
单例模式详解
java
我叫张土豆7 小时前
本体论、DDD、SDD、TDD:AI 编程时代的四层认知栈
java·人工智能