首页 > 其他分享 >面试~ThreadLocal

面试~ThreadLocal

时间:2022-09-06 12:11:26浏览次数:70  
标签:threadLocal 回收 面试 ThreadLocal 线程 引用 key


四种常见的引用

强引用---不可回收

软引用---内存不足即回收

弱引用---发现即回收

虚引用---形同虚设,目的是用于对象回收跟踪




ThreadLocal

1、ThreadLoca 是什么

ThreadLocal并不是一个Thread,而是Thread的局部变量

在jdk解决并发问题上,threadLocal是一种使用空间换时间的思路,ThreadLocal为每个线程提供一个独立的变量副本 解决了变量并发访问的冲突问题。

我的项目中,运用了threadLocal保存用户信息,实现客户端请求会话的隔离,保证了多用户的多会话请求的线程安全。

同时,使用完threadLocal后,删除value,防止了threadLocal引起的内存泄漏



★ threadLocal 为什么会导致内存泄漏----强引用、弱引用

----(这面试说强引用。弱引用。不是明摆着让面试官间JVM嘛)

主要是涉及到对象的强应用、弱引用问题

  • 强引用---不可回收
  • 弱引用---发现即回收

查看源码发现,每个线程都有一个自己的ThreadLocalMap对象,ThreadLocalMap的 key 是存储threadLocal的引用,vaule存储变量的副本



2、ThreadLocal的原理

1.ThreadLocal是Java中所提供的线程本地存储机制,可以利用该机制将数据缓存在某个线程内部,该线程可以在任意时刻、任意方法中获取缓存的数据

2.ThreadLocal底层是通过ThreadLocalMap来实现的,每个Thread对象(注意不是ThreadLocal对象)中都存在一个ThreadLocalMap,Map的key为 ThreadLocal对象,Map的value为需要缓存的值

其中,threadLocal对象是弱引用,在GC的时候,会被自动回收。而value就是ThreadLocal类 set设置的数据。value是强引用,不会被GC。

image



3、为什么用ThreadLocal做key?

不知道你有没有思考过这样一个问题:ThreadLocalMap为什么要用ThreadLocal做key,而不是用Thread做key?


确实,jdk早期的设计,是 threadLocal 维护 threadLocalMap,而线程作为key,

但是这种设计在 jdk8 之后,就被取代了,变成 thread 维护 threadLocalMap,而 threadLocal 作为 key

是因为我们知道线程的数量往往比threadLocal 多,jdk8的设计就可以使得 threadLocalMap 存储的 entry 数量变少。

也更加的节省了内存,当 thread 销毁了, 对应 threadLocalMap 也会被销毁

image



4、为什么把ThreadLocal设计成弱引用?

是最大程度的解决内存泄露问题,因为threadLocal 设计成弱引用,GC 的时候,发现它即可回收。

  • 使用get、set或remove方法清理key为null的value值



5、为什么内存泄露

  • 涉及到强引用和弱引用。因为我的项目为了查看文章详情同时更新阅读浏览数,引入了线程池。

  • 线程池中使用ThreadLocal会造成内存泄漏,因为当ThreadLocal对象使用完之后,应该要把设置的key,value,也就是Entry对象进行回收,

    但线程池中的线程不会回收,而线程对象是通过强引用指向ThreadLocalMapThreadLocalMap也是通过强引用指向Entry对象,线程不被回收,Entry对象也就不会被回收,从而出现内存泄漏

  • 解决办法是,在使用了ThreadLocal对象之后,手动调用ThreadLocal的remove方法,手动清除Entry对象



★ 项目细节:

使用一个拦截器拦截请求,从cookie中获取token字符串与redis中的token进行匹配,获取用户信息,将用户信息存储到ThreadLocal中,在本次请求中持有用户信息,即可在后续操作中使用到用户信息。

★ 项目细节:在登录拦截器中prehandle方法中:验证token成功后,将用户信息存储到threadLocal;在afterCompletion方法中:对threadLocal做了value的删除,防止内存泄漏。

标签:threadLocal,回收,面试,ThreadLocal,线程,引用,key
From: https://www.cnblogs.com/shan333/p/16661318.html

相关文章

  • 【面试题】js实现将excel表格copy到页面
    js实现将excel表格copy到页面点击打开视频讲解更加详细其实最核心的技术,还是copy的是我们粘贴板上的数据就像平常怎么粘贴复制其他的数据一样,只是我们在excel粘贴的是一......
  • 面试~线程池-三大方法、七个参数、四种拒绝策略、实际应用
    池化技术程序的运行,本质:占用系统的资源!优化资源的使用!=>池化技术线程池、连接池、内存池、对象池///.....创建、销毁。十分浪费资源池化技术:事先准备好一些资源,有......
  • 面试java并发~(lock、volatile、cas)
    Lock锁是一个接口,有三个实现类,分别是常用的可重入锁,读锁、写锁。常用的可重入锁,默认一般创建的是非公平锁,就是允许线程插队,而不是按先来后到顺序。非公平锁的目的:是为......
  • Vue-面试题之生命周期函数
    1.什么是生命周期函数?vue组件对象在创建到销毁的过程中,在某一种条件成立的时刻系统会去调用的vue中设定的函数这些函数都叫做:生命周期函数2.vue的命周期函数......
  • 面试突击80:说一下 Spring 中 Bean 的生命周期?
    Java中的公共类称之为Bean或JavaBean,而Spring中的Bean指的是将对象的生命周期,交个SpringIoC容器来管理的对象。所以Spring中的Bean对象在使用时,无需通过n......
  • 前端面试Ajxa常见问题整理
    1、Ajxa的交互流程有哪几步?(1)创建Ajxa对象xhr=newXMLHttpRequest(2)规定请求地址xhr.open(method,url,async)(3)等待服务器相应xhr.onload(4)向服务器发送请求xhr.send......
  • 【Java面试】面试自閟了!工作5年的小伙伴今天面试被吊打问我,并行和并发有什么区别?
    “并行和并发有什么区别?”关于这个问题,很多工作5年以上的同学都回答不出来。或者说,自己有一定的理解,但是不知道怎么表达。大家好,我是Mic,一个工作了14年的Java程序员。......
  • 组件基础(面试)
    组件组件是可复用的Vue实例,主要用于开发中具有相同特征不同数据的模块把它集成为一个组件供重复利用 组件基础(面试)1.全局组件:组件的属性不能用大写字母组件......
  • 生命周期函数(面试)
    生命周期函数 beforeCreate()created()beforeMount()Mounted()beforeUpdate()Updated()beforeDestroy()destroyed()//......
  • RocketMQ:RocketMQ常见面试题整理
    RocketMQ常见面试题整理MQ优缺点:优点:异步;解耦;削峰。RocketMQ默认端口号:9876。RocketMQ三大功能:缺点:系统可用性降低;系统复杂性提高;存在消息(数据)一致性问题。消息可靠......