ThreadLocal 面试六连问,你能 Hold 住吗?
点击上方“方志朋”,选择“设为星标”
回复”666“获取新整理的面试文章
转自:码农沉思录
中高级阶段开发者出去面试,应该躲不开ThreadLocal相关问题,本文就常见问题做出一些解答,欢迎留言探讨。
ThreadLocal为Java并发提供了一个新的思路, 它用来存储Thread的局部变量, 从而达到各个Thread之间的隔离运行。它被广泛应用于框架之间的用户资源隔离、事务隔离等。
但是用不好会导致内存泄漏, 本文重点用于对它的使用过程的疑难解答, 相信仔细阅读完后的朋友可以随心所欲的安全使用它。
一、内存泄漏原因探索
ThreadLocal操作不当会引发内存泄露,最主要的原因在于它的内部类ThreadLocalMap中的Entry的设计。
Entry继承了WeakReference<ThreadLocal<?>>,即Entry的key是弱引用,所以key'会在垃圾回收的时候被回收掉, 而key对应的value则不会被回收, 这样会导致一种现象:key为null,value有值。
key为空的话value是无效数据,久而久之,value累加就会导致内存泄漏。
二、怎么解决这个内存泄漏问题
每次使用完ThreadLocal都调用它的remove()方法清除数据。因为它的remove方法会主动将当前的key和value(Entry)进行清除。
e.clear()用于清除Entry的key,它调用的是WeakReference中的方法:this.referent = null
expungeStaleEntry(i)用于清除Entry对应的value, 这个后面会详细讲。
三、JDK开发者是如何避免内存泄漏的
ThreadLocal的设计者也意识到了这一点(内存泄漏), 他们在一些方法中埋了对key=null的value擦除操作。
这里拿ThreadLocal提供的get()方法举例,它调用了ThreadLocalMap#getEntry()方法,对key进行了校验和对null key进行擦除。
如果key为null, 则会调用getEntryAfterMiss()方法,在这个方法中,如果k == null , 则调用expungeStaleEntry(i);方法。
expungeStaleEntry(i)方法完成了对key=null 的key所对应的value进行赋空, 释放了空间避免内存泄漏。
同时它遍历下一个key为空的entry, 并将value赋值为null, 等待下次GC释放掉其空间。
同理, set()方法最终也是调用该方法(expungeStaleEntry), 调用路径:
set(T value)->
map.set(this, value)->
rehash()->
expungeStaleEntries()
remove方法
remove()->
ThreadLocalMap.remove(this)->
expungeStaleEntry(i)
这样做, 也只能说尽可能避免内存泄漏, 但并不会完全解决内存泄漏这个问题。比如极端情况下我们只创建ThreadLocal但不调用set、get、remove方法等。所以最能解决问题的办法就是用完ThreadLocal后手动调用remove().
四、手动释放ThreadLocal遗留存储?你怎么去设计/实现?
这里主要是强化一下手动remove的思想和必要性,设计思想与连接池类似。
包装其父类remove方法为静态方法,如果是spring项目, 可以借助于bean的声明周期, 在拦截器的afterCompletion阶段进行调用。
弱引用导致内存泄漏,那为什么key不设置为强引用
这个问题就比较有深度了,是你谈薪的小小资本。
如果key设置为强引用, 当threadLocal实例释放后, threadLocal=null, 但是threadLocal会有强引用指向threadLocalMap,threadLocalMap.Entry又强引用threadLocal, 这样会导致threadLocal不能正常被GC回收。
弱引用虽然会引起内存泄漏, 但是也有set、get、remove方法操作对null key进行擦除的补救措施, 方案上略胜一筹。
线程执行结束后会不会自动清空Entry的value
一并考察了你的gc基础。
事实上,当currentThread执行结束后, threadLocalMap变得不可达从而被回收,Entry等也就都被回收了,但这个环境就要求不对Thread进行复用,但是我们项目中经常会复用线程来提高性能, 所以currentThread一般不会处于终止状态。
五、Thread和ThreadLocal有什么联系呢
ThreadLocal的概念。
Thread和ThreadLocal是绑定的, ThreadLocal依赖于Thread去执行, Thread将需要隔离的数据存放到ThreadLocal(准确的讲是ThreadLocalMap)中, 来实现多线程处理。
六、Spring如何处理Bean多线程下的并发问题
ThreadLocal天生为解决相同变量的访问冲突问题, 所以这个对于spring的默认单例bean的多线程访问是一个完美的解决方案。spring也确实是用了ThreadLocal来处理多线程下相同变量并发的线程安全问题。
spring 如何保证数据库事务在同一个连接下执行的?
要想实现jdbc事务, 就必须是在同一个连接对象中操作, 多个连接下事务就会不可控, 需要借助分布式事务完成。那spring 如何保证数据库事务在同一个连接下执行的呢?
DataSourceTransactionManager 是spring的数据源事务管理器, 它会在你调用getConnection()的时候从数据库连接池中获取一个connection, 然后将其与ThreadLocal绑定, 事务完成后解除绑定。这样就保证了事务在同一连接下完成。
概要源码:
1.事务开始阶段:
org.springframework.jdbc.datasource.DataSourceTransactionManager#doBegin->TransactionSynchronizationManager#bindResource->org.springframework.transaction.support.TransactionSynchronizationManager#bindResource
2.事务结束阶段:
org.springframework.jdbc.datasource.DataSourceTransactionManager#doCleanupAfterCompletion->TransactionSynchronizationManager#unbindResource->org.springframework.transaction.support.TransactionSynchronizationManager#unbindResource->TransactionSynchronizationManager#doUnbindResource
热门内容:Spring的Controller是单例还是多例?怎么保证并发的安全一款直击痛点的优秀http框架,让我超高效率完成了和第三方接口的对接
Spring Boot 中的 RestTemplate不好用?试试 Retrofit !为什么建议大家使用 Linux 开发?爽(外加七个感叹号)最近面试BAT,整理一份面试资料《Java面试BAT通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。
明天见(。・ω・。)ノ
ThreadLocal 面试六连问,你能 Hold 住吗?相关推荐
- TCP 协议面试灵魂 12 问 | 强势整理
点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 来源 | urlify.cn/rqumIn 先亮出这篇文 ...
- Spring面试五连问,这怎么顶啊
最近有小伙伴跟我聊最近找工作的情况,疯狂投简历,有的石沉大海,但还好不是全军覆没.前两天好不容易熬到了阿里的四面,一波Spring相关的连击,有点懵逼,过来复盘一下面试内容. 前面几题还好,问的是有关 ...
- 面试中常问的List去重问题,你都答对了吗?
面试中经常被问到的list如何去重,用来考察你对list数据结构,以及相关方法的掌握,体现你的java基础学的是否牢固. 我们大家都知道,set集合的特点就是没有重复的元素.如果集合中的数据类型是基本 ...
- TCP协议面试灵魂10问 | 强势整理
点击上方"朱小厮的博客",选择"设为星标" 后台回复"加群",加入新技术 来源 | urlify.cn/rqumIn 先亮出这篇文章的思维导 ...
- 面试:TCP协议面试10连问,总会用得到,值得收藏!
阅读本文大概需要 18 分钟. 来自:juejin.im/post/5e527c58e51d4526c654bf41 先亮出这篇文章的思维导图 TCP 作为传输层的协议,是一个软件工程师素养的体现,也 ...
- 《失业七个月,面试六十家公司》的深圳体验
<失业七个月,面试六十家公司>的深圳体验 作者:色里调情 <失业a 七个月,面试六十家公司>的深圳体验 首先,坦白的讲,如果我现在不是找到了一份还合适的工作,我是根本不愿意 ...
- 最新校招笔试面试六十题
原文: 九月十月百度,迅雷,华为,阿里巴巴最新校招笔试面试六十题(11.05) 链接:http://blog.csdn.net/v_july_v/article/details/11921021 分类 ...
- 面试官:hold住了八股和算法,扫码登录应该怎么实现你总不会了吧
真实面试小场景: 经过八股和算法的交锋,老三松了口气,都hold住了.只见面试官微微一笑,"其实,我真正想问的是--你觉得扫码登录应该怎么实现." 老三:"啊--这个,哦 ...
- TCP协议面试10连问,网友直呼太强!
来源:juejin.im/post/5e527c58e51d4526c654bf41 先亮出这篇文章的思维导图 TCP 作为传输层的协议,是一个软件工程师素养的体现,也是面试中经常被问到的知识点.在此 ...
最新文章
- 搜python编程题_100+Python编程题给你练~(附答案)
- Android 图片放错位置会拉伸变形
- 进程保护 (非Hook;非DKOM)
- Redis批量操作详解及性能分析
- asp.net core 环境(Development、Staging 、Production)
- activemq部署安装
- 在没人相信的时候,你的坚持才真正可贵
- npm安装vue-cli时报错解决方法
- RocketMq单机和集群搭建教程
- 自动化测试指南-自动化测试工程师必备的技能
- Camel In Action 读书笔记 (8)
- 堪比ps:Affinity Photo for mac(专业修图软件)
- (转)“宇宙之王”高盛在历史的交叉口,不得不全面走向机器自动化
- pdf需要简体中文语言支持包_收集全网最好用的PDF转Word工具,赶快收藏起来!...
- es6——模板字符串
- 华大单片机开发板HC32L13X上手入门
- 设置好DNS如何检测是是否正确正常通
- 用C语言解一元二次方程
- 对话冉小波:NULS三年来的实战心得与反思 |链捕手
- 开启这个数据缓存,一键加速你的小程序。