当前位置:首页 > 科技  > 软件

谈谈你对ThreadLocal的理解

来源: 责编: 时间:2023-11-28 17:11:50 353观看
导读思考:对ThreadLocal的理解多少?springboot葵花宝典主要分享JAVA技术,主要包含SpringBoot、SpingCloud、Docker、中间件等技术,以及Github开源项目1.ThreadLocal概述ThreadLocal是多线程中对于解决线程安全的一个操作类


exw28资讯网——每日最新资讯28at.com

图片exw28资讯网——每日最新资讯28at.com

思考:对ThreadLocal的理解多少?exw28资讯网——每日最新资讯28at.com

springboot葵花宝典exw28资讯网——每日最新资讯28at.com

主要分享JAVA技术,主要包含SpringBoot、SpingCloud、Docker、中间件等技术,以及Github开源项目exw28资讯网——每日最新资讯28at.com

1.ThreadLocal概述

ThreadLocal是多线程中对于解决线程安全的一个操作类,它会为每个线程都分配一个独立的线程副本从而解决了变量并发访问冲突的问题。ThreadLocal 同时实现了线程内的资源共享exw28资讯网——每日最新资讯28at.com

案例:使用JDBC操作数据库时,会将每一个线程的Connection放入各自的ThreadLocal中,从而保证每个线程都在各自的 Connection 上进行数据库的操作,避免A线程关闭了B线程的连接。exw28资讯网——每日最新资讯28at.com

图片图片exw28资讯网——每日最新资讯28at.com

2. ThreadLocal的实现原理&源码解析

ThreadLocal本质来说就是一个线程内部存储类,从而让多个线程只操作自己内部的值,从而实现线程数据隔离exw28资讯网——每日最新资讯28at.com

每个线程内有一个 ThreadLocalMap 类型的成员变量,用来存储资源对象exw28资讯网——每日最新资讯28at.com

图片图片exw28资讯网——每日最新资讯28at.com

ThreadLocalMap 的一些特点exw28资讯网——每日最新资讯28at.com

key 的 hash 值统一分配exw28资讯网——每日最新资讯28at.com

初始容量 16,扩容因子 2/3,扩容容量翻倍exw28资讯网——每日最新资讯28at.com

key 索引冲突后用开放寻址法解决冲突exw28资讯网——每日最新资讯28at.com

2.1. ThreadLocal基本使用

set(value) 设置值:  以 ThreadLocal 自己作为 key,资源对象作为 value,放入当前线程的 ThreadLocalMap 集合中exw28资讯网——每日最新资讯28at.com

get() 获取值: 以 ThreadLocal 自己作为 key,到当前线程中查找关联的资源值exw28资讯网——每日最新资讯28at.com

remove() 清除值: 以 ThreadLocal 自己作为 key,移除当前线程关联的资源值exw28资讯网——每日最新资讯28at.com

代码案例exw28资讯网——每日最新资讯28at.com

public class ThreadLocalTest {    static ThreadLocal<String> 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();    }}

3. ThreadLocal-内存泄露问题

在介绍内存泄露问题问题之前先介绍一下Java对象中的四种引用类型:Java对象中的四种引用类型:exw28资讯网——每日最新资讯28at.com

  • 强引用: 最为普通的引用方式,表示一个对象处于有用且必须的状态,如果一个对象具有强引用,则GC并不会回收它。即便堆中内存不足了,宁可出现OOM,也不会对其进行回收
Object obj = new Object();
  • 软引用:软引用用于描述一些还有用但并非必须保持的对象。在系统即将发生内存溢出之前,垃圾收集器会清理这些软引用指向的对象
Object obj = new Object();SoftReference<Object> softRef = new SoftReference<>(obj);
  • 弱引用:表示一个对象处于可能有用且非必须的状态。在GC线程扫描内存区域时,一旦发现弱引用,就会回收到弱引用相关联的对象。对于弱引用的回收,无关内存区域是否足够,一旦发现则会被回收
Object obj = new Object();WeakReference<Object> weakRef = new WeakReference<>(obj);
  • 虚引用:虚引用也称为幽灵引用,它几乎没有实际意义,主要用于跟踪对象被垃圾收集的活动;虚引用不能单独使用,必须与引用队列(ReferenceQueue)一起使用。当垃圾收集器准备回收一个对象时,如果发现它有虚引用,会把这个虚引用加入到与之关联的引用队列中
Object obj = new Object();PhantomReference<Object> phantomRef = new PhantomReference<>(obj, referenceQueue);

3.1. ThreadLocal-内存泄露问题

每一个Thread维护一个ThreadLocalMap,在ThreadLocalMap中的Entry对象继承了WeakReference,其中key为使用弱引用的ThreadLocal实例,value为线程变量的副本exw28资讯网——每日最新资讯28at.com

图片图片exw28资讯网——每日最新资讯28at.com

ThreadLocalMap 中的 key 被设计为弱引用,原因如下exw28资讯网——每日最新资讯28at.com

Thread 可能需要长时间运行(如线程池中的线程),如果 key 不再使用,需要在内存不足(GC)时释放其占用的内存exw28资讯网——每日最新资讯28at.com

内存释放时机exw28资讯网——每日最新资讯28at.com

  • 被动 GC 释放 key

仅是让 key 的内存释放,关联 value 的内存并不会释放exw28资讯网——每日最新资讯28at.com

  • 懒惰被动释放 value
  • get key 时,发现是 null key,则释放其 value 内存
  • set key 时,会使用启发式扫描,清除临近的 null key 的 value 内存,启发次数与元素个数,是否发现 null key 有关
  • 主动 remove 释放 key,value
  • 会同时释放 key,value 的内存,也会清除临近的 null key 的 value 内存
  • 推荐使用它,因为一般使用 ThreadLocal 时都把它作为静态变量(即强引用),因此无法被动依靠 GC 回收

4. ThreadLocal面试题

面试官:谈谈你对ThreadLocal的理解exw28资讯网——每日最新资讯28at.com

候选人:exw28资讯网——每日最新资讯28at.com

ThreadLocal 主要功能有两个:exw28资讯网——每日最新资讯28at.com

  • 第一个是可以实现资源对象的线程隔离,让每个线程各用各的资源对象,避免争用引发的线程安全问题
  • 第二个是实现了线程内的资源共享

面试官:好的,那你知道ThreadLocal的底层原理实现吗?exw28资讯网——每日最新资讯28at.com

候选人:exw28资讯网——每日最新资讯28at.com

在ThreadLocal内部维护了一个一个 ThreadLocalMap 类型的成员变量,用来存储资源对象exw28资讯网——每日最新资讯28at.com

当我们调用 set 方法,就是以 ThreadLocal 自己作为 key,资源对象作为 value,放入当前线程的 ThreadLocalMap 集合中exw28资讯网——每日最新资讯28at.com

当调用 get 方法,就是以 ThreadLocal 自己作为 key,到当前线程中查找关联的资源值exw28资讯网——每日最新资讯28at.com

当调用 remove 方法,就是以 ThreadLocal 自己作为 key,移除当前线程关联的资源值exw28资讯网——每日最新资讯28at.com

面试官:好的,那关于ThreadLocal会导致内存溢出这个事情,了解吗?exw28资讯网——每日最新资讯28at.com

候选人:exw28资讯网——每日最新资讯28at.com

是应为ThreadLocalMap 中的 key 被设计为弱引用,它是被动的被GC调用释放key,不过关键的是只有key可以得到内存释放,而value不会,因为value是一个强引用。exw28资讯网——每日最新资讯28at.com

在使用ThreadLocal 时都把它作为静态变量(即强引用),因此无法被动依靠 GC 回收,建议主动的remove 释放 key,这样就能避免内存溢出。exw28资讯网——每日最新资讯28at.com


exw28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-34920-0.html谈谈你对ThreadLocal的理解

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: StarRocks在支付对账领域的应用

下一篇: 大型直播活动保障S13的实践和思考

标签:
  • 热门焦点
  • Redmi Buds 4开箱简评:才199还有降噪 可以无脑入

    在上个月举办的Redmi Note11T Pro系列新机发布会上,除了两款手机新品之外,Redmi还带来了两款TWS真无线蓝牙耳机产品,Redmi Buds 4和Redmi Buds 4 Pro,此前我们在Redmi Note11T
  • 6月安卓手机性能榜:vivo/iQOO霸占旗舰排行榜前三

    2023年上半年已经正式过去了,我们也迎来了安兔兔V10版本,在新的骁龙8Gen3和天玑9300发布之前,性能榜的榜单大体会以骁龙8Gen2和天玑9200+为主,至于那颗3.36GHz的骁龙8Gen2领先
  • Rust中的高吞吐量流处理

    作者 | Noz编译 | 王瑞平本篇文章主要介绍了Rust中流处理的概念、方法和优化。作者不仅介绍了流处理的基本概念以及Rust中常用的流处理库,还使用这些库实现了一个流处理程序
  • 19个 JavaScript 单行代码技巧,让你看起来像个专业人士

    今天这篇文章跟大家分享18个JS单行代码,你只需花几分钟时间,即可帮助您了解一些您可能不知道的 JS 知识,如果您已经知道了,就当作复习一下,古人云,温故而知新嘛。现在,我们就开始今
  • 重估百度丨“晚熟”的百度云,能等到春天吗?

    &copy;自象限原创作者|程心排版|王喻可2016年7月13日,百度云计算战略发布会在北京举行,宣告着百度智能云的正式启程。彼时的会场座无虚席,甚至排队排到了门外,在场的所有人几乎都
  • 自律,给不了Keep自由!

    来源 | 互联网品牌官作者 | 李大为编排 | 又耳 审核 | 谷晓辉自律能不能给用户自由暂时不好说,但大概率不能给Keep自由。近日,全球最大的在线健身平台Keep正式登陆港交所,努力
  • 当家的盒马,加速谋生

    来源 | 价值星球Planet作者 | 归去来自己&ldquo;当家&rdquo;的盒马,开始加速谋生了。据盒马官微消息,盒马计划今年开放生鲜供应链,将其生鲜商品送往食堂。目前,盒马在上海已经与
  • 华为Mate 60系列用上可变灵动岛:正式版体验将会更出色

    这段时间以来,关于华为新旗舰的爆料日渐密集。据此前多方爆料,今年华为将开始恢复一年双旗舰战略,除上半年推出的P60系列外,往年下半年的Mate系列也将
  • 朋友圈可以修改可见范围了 苹果用户可率先体验

    近日,iOS用户迎来微信8.0.27正式版更新,除了可更换二维码背景外,还新增了多项实用功能。在新版微信中,朋友圈终于可以修改可见范围,简单来说就是已发布的朋友圈
Top