思考:对ThreadLocal的理解多少?
成都创新互联公司服务项目包括红旗网站建设、红旗网站制作、红旗网页制作以及红旗网络营销策划等。多年来,我们专注于互联网行业,利用自身积累的技术优势、行业经验、深度合作伙伴关系等,向广大中小型企业、政府机构等提供互联网行业的解决方案,红旗网站推广取得了明显的社会效益与经济效益。目前,我们服务的客户以成都为中心已经辐射到红旗省份的部分城市,未来相信会继续扩大服务区域并继续获得客户的支持与信任!
springboot葵花宝典
主要分享JAVA技术,主要包含SpringBoot、SpingCloud、Docker、中间件等技术,以及Github开源项目
ThreadLocal是多线程中对于解决线程安全的一个操作类,它会为每个线程都分配一个独立的线程副本从而解决了变量并发访问冲突的问题。ThreadLocal 同时实现了线程内的资源共享
案例:使用JDBC操作数据库时,会将每一个线程的Connection放入各自的ThreadLocal中,从而保证每个线程都在各自的 Connection 上进行数据库的操作,避免A线程关闭了B线程的连接。
图片
ThreadLocal本质来说就是一个线程内部存储类,从而让多个线程只操作自己内部的值,从而实现线程数据隔离
每个线程内有一个 ThreadLocalMap 类型的成员变量,用来存储资源对象
图片
ThreadLocalMap 的一些特点
key 的 hash 值统一分配
初始容量 16,扩容因子 2/3,扩容容量翻倍
key 索引冲突后用开放寻址法解决冲突
set(value) 设置值: 以 ThreadLocal 自己作为 key,资源对象作为 value,放入当前线程的 ThreadLocalMap 集合中
get() 获取值: 以 ThreadLocal 自己作为 key,到当前线程中查找关联的资源值
remove() 清除值: 以 ThreadLocal 自己作为 key,移除当前线程关联的资源值
代码案例
public class ThreadLocalTest {
static ThreadLocal threadLocal = new ThreadLocal<>();
public static void main(String[] args) {
new Thread(() -> {
String name = Thread.currentThread().getName();
threadLocal.set("zbbmeta");
print(name);
System.out.println(name + "-after remove : " + threadLocal.get());
}, "t1").start();
new Thread(() -> {
String name = Thread.currentThread().getName();
threadLocal.set("zbbmeta");
print(name);
System.out.println(name + "-after remove : " + threadLocal.get());
}, "t2").start();
}
static void print(String str) {
//打印当前线程中本地内存中本地变量的值
System.out.println(str + " :" + threadLocal.get());
//清除本地内存中的本地变量
threadLocal.remove();
}
}
在介绍内存泄露问题问题之前先介绍一下Java对象中的四种引用类型:Java对象中的四种引用类型:
Object obj = new Object();
Object obj = new Object();
SoftReference
Object obj = new Object();
WeakReference
Object obj = new Object();
PhantomReference
每一个Thread维护一个ThreadLocalMap,在ThreadLocalMap中的Entry对象继承了WeakReference,其中key为使用弱引用的ThreadLocal实例,value为线程变量的副本
图片
ThreadLocalMap 中的 key 被设计为弱引用,原因如下
Thread 可能需要长时间运行(如线程池中的线程),如果 key 不再使用,需要在内存不足(GC)时释放其占用的内存
内存释放时机
仅是让 key 的内存释放,关联 value 的内存并不会释放
面试官:谈谈你对ThreadLocal的理解
候选人:
ThreadLocal 主要功能有两个:
- 第一个是可以实现资源对象的线程隔离,让每个线程各用各的资源对象,避免争用引发的线程安全问题
- 第二个是实现了线程内的资源共享
面试官:好的,那你知道ThreadLocal的底层原理实现吗?
候选人:
在ThreadLocal内部维护了一个一个 ThreadLocalMap 类型的成员变量,用来存储资源对象
当我们调用 set 方法,就是以 ThreadLocal 自己作为 key,资源对象作为 value,放入当前线程的 ThreadLocalMap 集合中
当调用 get 方法,就是以 ThreadLocal 自己作为 key,到当前线程中查找关联的资源值
当调用 remove 方法,就是以 ThreadLocal 自己作为 key,移除当前线程关联的资源值
面试官:好的,那关于ThreadLocal会导致内存溢出这个事情,了解吗?
候选人:
是应为ThreadLocalMap 中的 key 被设计为弱引用,它是被动的被GC调用释放key,不过关键的是只有key可以得到内存释放,而value不会,因为value是一个强引用。
在使用ThreadLocal 时都把它作为静态变量(即强引用),因此无法被动依靠 GC 回收,建议主动的remove 释放 key,这样就能避免内存溢出。
网页标题:谈谈你对ThreadLocal的理解
分享URL:http://www.csdahua.cn/qtweb/news37/499837.html
网站建设、网络推广公司-快上网,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 快上网