点击上方“方志朋”,选择“设为星标”

回复”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 住吗?相关推荐

  1. TCP 协议面试灵魂 12 问 | 强势整理

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 来源 | urlify.cn/rqumIn 先亮出这篇文 ...

  2. Spring面试五连问,这怎么顶啊

    最近有小伙伴跟我聊最近找工作的情况,疯狂投简历,有的石沉大海,但还好不是全军覆没.前两天好不容易熬到了阿里的四面,一波Spring相关的连击,有点懵逼,过来复盘一下面试内容. 前面几题还好,问的是有关 ...

  3. 面试中常问的List去重问题,你都答对了吗?

    面试中经常被问到的list如何去重,用来考察你对list数据结构,以及相关方法的掌握,体现你的java基础学的是否牢固. 我们大家都知道,set集合的特点就是没有重复的元素.如果集合中的数据类型是基本 ...

  4. TCP协议面试灵魂10问 | 强势整理

    点击上方"朱小厮的博客",选择"设为星标" 后台回复"加群",加入新技术 来源 | urlify.cn/rqumIn 先亮出这篇文章的思维导 ...

  5. 面试:TCP协议面试10连问,总会用得到,值得收藏!

    阅读本文大概需要 18 分钟. 来自:juejin.im/post/5e527c58e51d4526c654bf41 先亮出这篇文章的思维导图 TCP 作为传输层的协议,是一个软件工程师素养的体现,也 ...

  6. 《失业七个月,面试六十家公司》的深圳体验

    <失业七个月,面试六十家公司>的深圳体验 作者:色里调情 <失业a 七个月,面试六十家公司>的深圳体验 首先,坦白的讲,如果我现在不是找到了一份还合适的工作,我是根本不愿意 ...

  7. 最新校招笔试面试六十题

    原文: 九月十月百度,迅雷,华为,阿里巴巴最新校招笔试面试六十题(11.05) 链接:http://blog.csdn.net/v_july_v/article/details/11921021 分类 ...

  8. 面试官:hold住了八股和算法,扫码登录应该怎么实现你总不会了吧

    真实面试小场景: 经过八股和算法的交锋,老三松了口气,都hold住了.只见面试官微微一笑,"其实,我真正想问的是--你觉得扫码登录应该怎么实现." 老三:"啊--这个,哦 ...

  9. TCP协议面试10连问,网友直呼太强!

    来源:juejin.im/post/5e527c58e51d4526c654bf41 先亮出这篇文章的思维导图 TCP 作为传输层的协议,是一个软件工程师素养的体现,也是面试中经常被问到的知识点.在此 ...

最新文章

  1. 搜python编程题_100+Python编程题给你练~(附答案)
  2. Android 图片放错位置会拉伸变形
  3. 进程保护 (非Hook;非DKOM)
  4. Redis批量操作详解及性能分析
  5. asp.net core 环境(Development、Staging 、Production)
  6. activemq部署安装
  7. 在没人相信的时候,你的坚持才真正可贵
  8. npm安装vue-cli时报错解决方法
  9. RocketMq单机和集群搭建教程
  10. 自动化测试指南-自动化测试工程师必备的技能
  11. Camel In Action 读书笔记 (8)
  12. 堪比ps:Affinity Photo for mac(专业修图软件)
  13. (转)“宇宙之王”高盛在历史的交叉口,不得不全面走向机器自动化
  14. pdf需要简体中文语言支持包_收集全网最好用的PDF转Word工具,赶快收藏起来!...
  15. es6——模板字符串
  16. 华大单片机开发板HC32L13X上手入门
  17. 设置好DNS如何检测是是否正确正常通
  18. 用C语言解一元二次方程
  19. 对话冉小波:NULS三年来的实战心得与反思 |链捕手
  20. 开启这个数据缓存,一键加速你的小程序。

热门文章

  1. echarts - 条形图grid设置距离绘图区域的距离
  2. 洛谷 - P1426 - 小鱼会有危险吗 - 模拟
  3. sendmail configuration on HP-UX
  4. Datawhale组队学习周报(第041周)
  5. 如何利用 C# 实现神经网络的感知器模型?
  6. 【UVA】10152 ShellSort (几只乌龟的故事)
  7. 第二弹,坐地铁就能学会的3种「非常有趣」的 Python 玩法
  8. 顺络新能源汽车技术研讨会圆满落幕
  9. 给你一个热爱阅读的机会,走到哪儿,看到哪儿的读书体验
  10. 赠书 | 图解机器学习算法,看这文就够了!