type
status
date
slug
summary
tags
category
icon
password
Property
Feb 6, 2025 04:01 AM
本篇文章主要讲解Java中的ThreadLocal

ThreadLocal的基本实现

一、结构与定义

1.1 ThreadLocal的基本定义与基本实现

学习不是为了简单去看,要思考,也就是发掘隐含在所见事务中的思想。

1.2 ThreadLocalMap如何解决Hash冲突的?

解决Hash冲突一共有这些方法:
  1. 链地址法(拉链法)
    1. 链地址法是通过在哈希表的每个位置存储一个链表,将所有哈希值相同的元素存储在同一链表中。当发生冲突时,直接将冲突元素加入到对应位置的链表中。这种方法的优点是实现简单、删除操作方便,但查找效率较低,尤其是在链表较长的情况下。
  1. 开放定址法(开放寻址法)
    1. 开放定址法通过探测技术(如线性探测、二次探测、伪随机探测等)在哈希表中寻找下一个空位置存储冲突元素。具体实现方式包括:
      • 线性探测:从冲突位置开始顺序查找下一个空位置。其中,ThreadLocalMap使用的就是此方法。
      • 二次探测:利用公式 H(i)=(H(key)+di)mod md 为增量序列,如 1,−1,1,−1,…)寻找下一个位置。
      • 伪随机探测:使用伪随机数生成器选择下一个位置。此方法避免了链表的使用,但可能导致聚集现象,影响性能。
  1. 再哈希法(再散列法)
    1. 再哈希法通过构造多个哈希函数,在发生冲突时依次尝试其他哈希函数,直到找到不冲突的位置为止。这种方法虽然可以减少冲突,但会增加计算时间。
  1. 建立公共溢出区
    1. 当哈希表接近满载时,可以将冲突元素存储在额外的溢出区中,而不是直接存入哈希表。这种方法适用于哈希表容量较大且冲突较少的情况。
  1. 合并哈希法
    1. 合并哈希法结合了多个哈希函数,通过计算多个哈希值来避免聚集问题。这种方法需要额外的空间存储多个哈希值。
      notion image
  1. Cuckoo Hashing(库库哈希法)
    1. Cuckoo Hashing是一种基于两个独立哈希表和两个独立哈希函数的算法,通过交换位置的方式解决冲突。虽然能提供较快的查找效率,但可能导致死锁。
  1. 扩展式哈希(可扩展哈希)
    1. 扩展式哈希通过在磁盘块中存储多个记录,避免将所有数据存储在内存中。这种方法适用于数据量非常大的场景

二、实际使用场景

2.1 通常建议定义ThreadLocal为静态的

为什么ThreadLocal在日常使用的时候,我们通常需要在一个线程内传递状态,此时就可以使用ThreadLocal。一般建议定义为Static,针对同样的业务属性,每一个线程都会有自己的业务副本,如果使用ThreadLocal来进行存储临时信息,那么就可以所有线程的ThreadLocalMap存储相同的key,value根据不同业务需求,存储不同的数据,举一个最常见的例子:HttpServlet请求中,每一个HTTP请求都会对应一个Thread,此时如果我们需要每一次请求存储当前请求用户的临时信息,跟随请求的生命周期,那么就可以通过ThreadLocal来实现啦。

2.2 内存泄露注意

ThreadLocal用的不恰当是会出现内存泄漏的,如果你是基于线程池使用多线程,并且在多线程中使用了线程副本,ThreadLocal,就会出现内存泄露的可能。因为多线程中,线程一般是会保留的,不会直接销毁,如果你存储了数据在ThreadLocalMap中,需要在使用完之后及时remove,否则就会出现内存泄露,GC多次内存都得不到释放,在廖雪峰老师的博客中也提到过,一定要注意,如果是在try过程中使用的ThreadLocal一定要在finally中清除。

三、底层实现以及一些原理

3.1 ThreadLocalMap解决Hash冲突实现原理

ThreadLocalMap的底层源码如图,ThreadLocalMap定义在ThreadLocal中,使用是在Thread中,作为成员变量存在的,在处理冲突的时候,采用的开放定址法,线性探测。
notion image

3.2 学无止尽,未完待续

 
 
💡
有关ThreadLocal文章的问题,欢迎您在底部评论区留言,一起交流~
 
 
相关文章
计算机视觉(一):深度学习的人脸应用
Lazy loaded image
计算机视觉(二):特征向量计算
Lazy loaded image
计算机视觉(三):人脸识别之特征提取
Lazy loaded image
Flowable(一):Java知识学习
Lazy loaded image
Flowable(二):数据库篇
Lazy loaded image
Flowable(三):Liquibase模式管理
Lazy loaded image
JUC核心篇(二):JUC-UnSafe类的使用JUC核心篇(三):LockSupport与线程阻塞
Loading...
fntp
fntp
多一点兴趣,少一点功利
最新发布
作为Java程序员,最爱的一款字体推荐
2025-2-19
SpringBoot3单机Kafka服务
2025-2-19
Java小知识合集
2025-2-14
Spring笔记整理(一):InitializingBean的妙用
2025-2-7
JUC核心篇(五):JUC并发工具类的使用
2025-2-7
JUC核心篇(四):CAS与AQS
2025-2-7
公告
📝 博客只为了记录我的学习生涯
😎 我的学习目标是成为一名极客
🤖 我热爱开源当然我也拥抱开源
💌 我期待能收到你的Email留言
📧 我的邮箱:stickpoint@163.com
欢迎交流~