ThreadLocal
2023-05-14 14:26:48 9 举报
AI智能生成
ThreadLocal
作者其他创作
大纲/内容
简介
每个Thread维护一个ThreadLocalMap,这个Map的key是ThreadLocal实例本身,value才是真正要存储的值Object
- 每个Thread线程内部都有一个Map (ThreadLocalMap)
- Map`里面存储`ThreadLocal对象(key)`和`线程的变量副本(value)`
- Thread`内部的`Map`是由`ThreadLocal`维护的,由`ThreadLocal`负责向`map`获取和设置线程的变量值
- 对于不同的线程,每次获取副本值时,别的线程并不能获取到当前线程的副本值,形成了副本的隔离,互不干
如此设计的好处
每个Map存储的Entry数量就会变少。因为之前的存储数量由Thread的数量决定,现在是由ThreadLocal的数量决定。在实际运用当中,往往ThreadLocal的数量要少于Thread的数量
ThreadLocalMap 是由 Thread进行维护的吗,当Thread销毁之后,对应的ThreadLocalMap也会随之销毁,能减少内存的使用
核心方法
set
get
remove
initialValue
源码
基本结构
成员变量
存储结构-Entry
弱引用和内存泄漏
弱引用
垃圾回收器一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存
内存泄漏相关概念
Memory overflow:内存溢出,没有足够的内存提供申请者使用。
Memory leak:内存泄漏是指程序中已动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。内存泄漏的堆积终将导致内存溢出。
内存泄漏的原因
如果key使用强引用
如果key使用弱引用
出现内存泄漏的真实原因
避免内存泄漏的两种方式
1. 使用完ThreadLocal,调用其remove方法删除对应的Entry
2. 使用完ThreadLocal,当前Thread也随之运行结束
既然使用了弱引用也无法完全的避免内存溢出,为什么还要使用
在ThreadLocalMap中的 set/getEntry方法中,会对key为null(也即是ThreadLocal为null)进行判断,如果为null的话,那么是会对value置为null的。这就意味着使用完ThreadLocal,CurrentThread依然运行的前提下,就算忘记调用remove方法,弱引用比强引用可以多一层保障:弱引用的ThreadLocal会被回收,对应的value在下一次ThreadLocalMap调用 set、get、remove中的任一方法的时候会被清除,从而避免内存泄漏。
hash冲突的解决
添加菲波那切数列(黄金分割数)尽可能的避免hash冲突
int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY - 1)
int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY - 1)
避免不了使用 线性探测法
0 条评论
下一页