一、使用
val threadLocal = ThreadLocal<String>()
threadLocal.set("Hello,World");
val str = threadLocal.get()
二、作用:
为每个线程提供独享空间,以保存线程独享资源
三、原理:
- 每个线程
Thread中有1个threadLocals(ThreadLocalMap)变量
ThreadLocalMap的键Key= 当前ThreadLocal实例,值value= 该线程设置的存储在ThreadLocal变量的值- 该
key是ThreadLocal对象的弱引用;当要抛弃掉ThreadLocal对象时,垃圾收集器会忽略该key的引用而清理掉ThreadLocal对象
四、ThreadLocalMap
ThreadLocalMap 数据结构解析
哈希表特性
| 特性 | ThreadLocalMap | 说明 |
|---|---|---|
| 初始容量 | 16 | 2的幂次方 |
| 哈希函数 | key.hashCode() & (len-1) | 标准取模运算 |
| 冲突解决 | 开放地址法(线性探测) | 无链表结构 |
| 填充因子 | 2/3 (约66.7%) | 比HashMap的0.75更早扩容 |
| Key引用类型 | 弱引用 | 利于GC回收 |
| Value引用类型 | 强引用 | 需要主动清理避免内存泄漏 |
碰撞处理机制(线性探测法)
- 使用线性探测法处理hash冲突:
int nextIndex = i + 1 < len ? i + 1 : 0,即如果发生了冲突则循环选取下一个槽位存放,如果是最后一位发生冲突则选取第一位。 - 默认tab长度为16,扩容因子为2/3,threshold默认为16 * 2/3 = 10,size >= threshold触发清理检查,size >= threshold * 3/4 =8触发实际扩容。每次扩容为原来tab长度的2倍。