前言


在《透彻理解Spring事务设计思想之手写实现》中,已经向大家揭示了Spring就是利用ThreadLocal来实现一个线程中的Connection是同一个,从而保证了事务。本篇博客将带大家来深入分析ThreadLocal的实现原理。

ThreadLocal是什么、有什么、能做什么?

ThreadLocal提供一个线程(Thread)局部变量,访问到某个变量的每一个线程都拥有自己的局部变量。说白了,ThreadLocal就是想在多线程环境下去保证成员变量的安全。

ThreadLocal提供的方法

ThreadLocal API

对于ThreadLocal而言,常用的方法,就是get/set/initialValue方法。

我们先来看一个例子

demo

运行结果

是你想象中的结果么?

很显然,在这里,并没有通过ThreadLocal达到线程隔离的机制,可是ThreadLocal不是保证线程安全的么?这是什么鬼?

虽然,ThreadLocal让访问某个变量的线程都拥有自己的局部变量,但是如果这个局部变量都指向同一个对象呢?这个时候ThreadLocal就失效了。仔细观察下图中的代码,你会发现,threadLocal在初始化时返回的都是同一个对象a!

看一看ThreadLocal源码

我们直接看最常用的set操作:

set

线程局部变量

createMap

你会看到,set需要首先获得当前线程对象Thread;

然后取出当前线程对象的成员变量ThreadLocalMap;

如果ThreadLocalMap存在,那么进行KEY/VALUE设置,KEY就是ThreadLocal;

如果ThreadLocalMap没有,那么创建一个;

说白了,当前线程中存在一个Map变量,KEY是ThreadLocal,VALUE是你设置的值。

看一下get操作:

get

这里其实揭示了ThreadLocalMap里面的数据存储结构,从上面的代码来看,ThreadLocalMap中存放的就是Entry,Entry的KEY就是ThreadLocal,VALUE就是值。

ThreadLocalMap.Entry:

弱引用?

在JAVA里面,存在强引用、弱引用、软引用、虚引用。这里主要谈一下强引用和弱引用。

强引用,就不必说了,类似于:

A a = new A();

B b = new B();

考虑这样的情况:

C c = new C(b);

b = null;

考虑下GC的情况。要知道b被置为null,那么是否意味着一段时间后GC工作可以回收b所分配的内存空间呢?答案是否定的,因为即便b被置为null,但是c仍然持有对b的引用,而且还是强引用,所以GC不会回收b原先所分配的空间!既不能回收利用,又不能使用,这就造成了内存泄露

那么如何处理呢?

可以c = null;也可以使用弱引用!(WeakReference w = new WeakReference(b);)

分析到这里,我们可以得到:

内存结构图

这里我们思考一个问题:ThreadLocal使用到了弱引用,是否意味着不会存在内存泄露呢?

首先来说,如果把ThreadLocal置为null,那么意味着Heap中的ThreadLocal实例不再有强引用指向,只有弱引用存在,因此GC是可以回收这部分空间的,也就是key是可以回收的。但是value却存在一条从Current Thread过来的强引用链。因此只有当Current Thread销毁时,value才能得到释放。

因此,只要这个线程对象被gc回收,就不会出现内存泄露,但在threadLocal设为null和线程结束这段时间内不会被回收的,就发生了我们认为的内存泄露。最要命的是线程对象不被回收的情况,比如使用线程池的时候,线程结束是不会销毁的,再次使用的,就可能出现内存泄露。

那么如何有效的避免呢?

事实上,在ThreadLocalMap中的set/getEntry方法中,会对key为null(也即是ThreadLocal为null)进行判断,如果为null的话,那么是会对value置为null的。我们也可以通过调用ThreadLocal的remove方法进行释放!

好了,到这里,ThreadLocal的剖析就完成了,自己对ThreadLocal的认识又深入了些,^_^

手写系列相关爆文


【手写系列】写出我的第一个框架:迷你版Spring MVC

【手写系列】透彻理解Spring事务设计思想之手写实现

【手写系列】透彻理解MyBatis设计思想之手写实现

【手写系列】纯手写实现一个高可用的RPC

【手写系列】理解数据库连接池底层原理之手写实现

【手写系列】对HashMap的思考及手写实现

【手写系列】纯手写实现JDK动态代理

【手写系列】写一个迷你版的Tomcat

作者:张丰哲
链接:https://www.jianshu.com/p/ee8c9dccc953
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

对ThreadLocal实现原理的一点思考相关推荐

  1. [杂记]对RSA算法的数学原理的一点思考

    转载于:https://www.cnblogs.com/CQBZOIer-zyy/p/9808041.html

  2. java.lang.ThreadLocal实现原理和源码分析

    java.lang.ThreadLocal实现原理和源码分析 1.ThreadLocal的原理:为每一个线程维护变量的副本.某个线程修改的只是自己的副本. 2.ThreadLocal是如何做到把变量变 ...

  3. 对高并发流量控制的一点思考

    前言 在实际项目中,曾经遭遇过线上5W+QPS的峰值,也在压测状态下经历过10W+QPS的大流量请求,本篇博客的话题主要就是自己对高并发流量控制的一点思考. 应对大流量的一些思路 首先,我们来说一下什 ...

  4. 贝特朗奇论 用计算机,关于贝特朗奇论的一点思考

    关于贝特朗奇论的一点思考 贝特朗奇论这个名字就很奇怪,我最开始以为是贝特朗奇的某个论点或者命题,但是百度了一下发现原来是贝特朗(Bertrand)的"奇论",最初用以批判当时尚不严 ...

  5. 关于前端职业规划的一点思考

    自己目前已经工作3年了,最近也刚换了新工作,日常也一直在考虑自己的前端职业规划到底是怎样的,目前个人视角还不是很宽广,怕误人子弟,以下这篇文章有点启发,故转发供大家借鉴(里面有部分内容做了一些小修改) ...

  6. ”杠铃“策略:关于市场的一点思考,从转债到股票量化投研

    持续行动1期 46/100,"AI技术应用于量化投资研究". 第1期行动将近过半,进入一个"爬坡期". "低垂之果"基本上摘干净了,比如数据 ...

  7. 【模拟电路】对BJT的Ib为什么能控制Ic的一点思考和臆测

    [模拟电路]对BJT的Ib为什么能控制Ic的一点思考和臆测 首先声明一下,本人并非专门研究模电.晶体管原理的学者,如有纰漏或勘误,还请大佬指正.轻喷. 这是我读<模拟电子技术基础>(第五版 ...

  8. 30岁成不了技术专家就应该转做管理?希望通过本文给大家带来一点思考

    很多程序员都有一点技术情节,喜欢"专心搞技术",不喜欢管理,尤其管人.甚至为自己是"专注于技术"而自感清高,有点看不起那些"外行管理内行"或 ...

  9. mysql 手动写时间_关于数据库中如何存储时间的一点思考

    1.切记不要用字符串存储日期 我记得我在大学的时候就这样干过,而且现在很多对数据库不太了解的新手也会这样干,可见,这种存储日期的方式的优点还是有的,就是简单直白,容易上手. 但是,这是不正确的做法,主 ...

最新文章

  1. 潘云鹤:人工智能走向2.0 | 全球青少年图灵计划首场大师公开课
  2. visual studio如何给源码文件添加header信息?(创建者,创建日期等)(License Header Manager插件)
  3. html除左侧浮动,html清除浮动的6种方法示例
  4. Java0steam_Java学习 - Stream 使用
  5. emlog-FLY主题模板1.4版本免费完全开源
  6. ISCW实验10:安装SDM到路由器的FLASH中
  7. 拳王虚拟项目公社:如何通过知识付费赚钱,知识付费搬运赚钱,虚拟资源付费项目
  8. html中img显示旋转,css如何实现图片的旋转展示效果(代码示例)
  9. 数据中心运维管理经验39条
  10. jvisualVm用法
  11. Applese 的毒气炸弹(最小生成树)
  12. 人类(行为)动力学(1)——初步了解
  13. lintcode-微软笔试
  14. 节目源php代理_【斗鱼直播源】浏览器抓取真实直播源地址(纯前端JS PHP解析源码)...
  15. react native 背景颜色渐变
  16. Laravel将Word文档转化为pdf文件
  17. U盘打不开的常见情况和解决方法
  18. asp.net 是什么?
  19. python对于字典d d.get(x、y)_python--字典
  20. 2021-11-26 WPF上位机 96-Modbus通信代码的封装

热门文章

  1. php中的foreach和js中的foreach的用法和区别
  2. 说一说限制字数的输入框踩的坑
  3. Codeforces Round #351 (VK Cup 2016 Round 3, Div. 2 Edition) A. Bear and Game 水题
  4. Yik-Chung Wu ---Time synchronization for wireless sensor networks
  5. 专接本微型计算机原理考试,河北省2009年专接本-微型计算机原理与汇编语言试卷...
  6. sql server 2008 r2 没有维护计划_坚果R2发布,骁龙865+1亿像素+90Hz,4499元起
  7. 购物车清除的php,php-如何清除废弃的woocommerce购物车
  8. linux下打开配置文件命令_Linux下用户权限相关命令
  9. NMF 非负矩阵分解
  10. makefile 基础用法