一张图解决ThreadLocal
一张图解决ThreadLocal
一、前言
年底梳理知识体系时,研究了一下ThreadLocal的源码,整理了一张核心图。
想着,都走到这一步了,那就写一篇深度解读的文章吧。看过我之前文章的小伙伴都知道,我写博客,就喜欢写点别人没写的。要么就写个结构比别人好的。什么都不行,那就别写了。自己留着看就好了。
然后发现了ThreadLocal源码解读与ThreadLocal可能引起的内存泄露这样的优秀文章(两篇文章合起来,就更完整了),它把我要说的,差不多都说了。
所以,我就决定从精简(一张图)与认知过程两方面,写一篇辅助学习ThreadLocal的文章。
二、核心图
不啰嗦,核心图直接贴上。
根据核心图,已经对ThreadLocal了然于心的小伙伴,可以拿着图片,溜了溜了。
还想听我谈谈,我对ThreadLocal认知过程的小伙伴,可以留下来看看。
三、认知过程
话说,那是一个夜黑风高的夜晚,我躺在。。。
咳咳咳。抱歉,串场了。
最早接触ThreadLocal的时候,是在看面试教程的时候。我听到讲师balabala讲了一通,最后我脑海给ThreadLocal的第一印象就是,一个确保线程安全的线程变量(同一个变量,但每个线程都独立)。这个印象伴随了我大半年,反正我在那大半年也没用过。。。
后来,在一次看技术文章的时候,又看到了一篇ThreadLocal的介绍。通篇看下来,这篇文章说的内容,除了我学过的,就是总结了一句ThreadLocal可以简单看成一个Map<Thread, Object>。当时的我,还欣喜若狂,我终于懂得ThreadLocal的原理了。
再后来,我在微信的技术公众号中,看到ThreadLocal的内存泄漏问题。那篇文章把这个问题说得非常严重,搞得好像这个问题导致了二战爆发那么严重。如果不懂这个问题,就不配参加面试,不配呼吸这个世界的美好空气。。。幸好当时没人知道,我不懂这个东西。然后我就趁着午休的时间,速度翻了翻这篇文章。看完之后,脑海中的印象就是,ThreadLocal中的map的key是WeakReference,可能被清除,导致对应的value内存泄漏。
在接下来的小半年里,我也曾奇怪,如果ThreadLocal是一个Map<Thread, Object>,那为什么一个线程可以有多个ThreadLocal变量呢?为什么设置ThreadLocal变量时,还需要设置范型类型呢?
直到在学习另一个课程时,讲师提到栈封闭-ThreadLocal,才知道之前的认识是错误的。其实每个线程都有一个Map<ThreadLocal, Object>,这也解释了我之前的两个问题。但是当时由于工作与课程比较紧,还是没有查看源码。终究还是与ThreadLocal隔层纱。
最近临近年底,整理自己的知识体系。这次打算好好整理整理,所以就仔细阅读了ThreadLocal的源码。也知道之所以每个线程都有一个Map<ThreadLocal, Object>,是因为Thread有一个ThreadLocalMap(ThreadLocal内部类)变量。进而总结出了上面的核心图。
四、总结
之所以提到ThreadLocal的认识过程,其实是想表达:
- 认识是螺旋前进的
- 如无必要,不要过于追求认识的深度
- 想法要周全,执行要坚决
第一条的意思是,我们对某个事物的认识,往往伴随着正确&错误之间的游走。但是认识是在不断加深,变得更加全面的。
至于第二条,如果一开始我就强求看源码,那一定是事倍功半的。那时候的我对范型,弱应用等都了解太浅,缺乏足够的基础,让我一窥ThreadLocal的全貌。具体的反面教材,就是当时刚入Java坑的我,强行撸Spring源码。。。樯橹灰飞烟灭啊。。。
第三条,在自己有想法的时候,需要周全想法。如果有了决策结果,就应该去坚决地贯彻它。
不得不说,温故而知新啊。
愿与诸君共进步。
参考
一张图解决ThreadLocal的更多相关文章
- 一张图解决Struts2添加源码
主要是选择的路径:F:/struts2/struts-2.3.31/src/core/src/main/java
- 一张图彻底理解Spring如何解决循环依赖!!
写在前面 最近,在看Spring源码,看到Spring解决循环依赖问题的源码时,不得不说,源码写的太烂了.像Spring这种顶级的项目源码,竟然存在着这种xxx的代码.看了几次都有点头大,相信很多小伙 ...
- Nodejs学习笔记(三)——一张图看懂Nodejs建站
前言:一条线,竖着放,如果做不到精进至深,那就旋转90°,至少也图个幅度宽广. 通俗解释上面的胡言乱语:还没学会爬,就学起走了?! 继上篇<Nodejs学习笔记(二)——Eclipse中运行调试 ...
- 一张图告诉你为什么 Gmail 是最好的邮箱,以及大量私货
今天早上,我的同事详细介绍了 Gmail 相比其他邮箱的优势,比如强大的垃圾邮件过滤.简单的使用界面.强大的功能设置等等.但是对我来说,这些并不是我使用 Gmail 的最重要原因. 我第一个正式的邮箱 ...
- 一张图看懂DNS域名解析全过程
DNS域名解析是互联网上非常重要的一项服务,上网冲浪(还有人在用这个词吗?)伴随着大量DNS服务来支撑,而对于网站运营来说,DNS域名解析的稳定可靠,意味着更多用户的喜欢,更好的SEO效果和更大的访问 ...
- HTML5利用canvas,把多张图合并成一张图片
需求分析,根据当前网页中的几张图片,在手机上长按,保存图片到相册或者发送给好友. drawCanvas(){ var self = this; var imgsrcArray = [ require( ...
- SpringBoot图片上传(四) 一个input上传N张图,支持各种类型
简单介绍:需求上让实现,图片上传,并且可以一次上传9张图,图片格式还有要求,网上找了一个测试了下,好用,不过也得改,仅仅是实现了功能,其他不尽合理的地方,还需自己打磨. 代码: //html<d ...
- 一张图了解Spring Cloud微服务架构
Spring Cloud作为当下主流的微服务框架,可以让我们更简单快捷地实现微服务架构.Spring Cloud并没有重复制造轮子,它只是将目前各家公司开发的比较成熟.经得起实际考验的服务框架组合起来 ...
- 产品经理-需求分析-用户故事-敏捷开发 详解 一张图帮你了解Scrum敏捷流程
产品经理-需求分析-用户故事-敏捷开发 详解 用户故事是从用户的角度来描述用户渴望得到的功能.一个好的用户故事包括三个要素:1. 角色:谁要使用这个功能.2. 活动:需要完成什么样的功能.3. 商业价 ...
随机推荐
- 【Oracle】从删除的recyclebin中查看并恢复数据
如果数据库中用了drop删除表,后面没有加上purge的话,会出现在oracle的回收机制中 dba_recyclebin可以查看当前删除的都是哪些 这个只是部分截图,可以看到删除的对象是什么,删除的 ...
- C语言目的概念(C语言学习笔记)
什么是目 目是针对操作符来说的,一个操作符影响两个操作数就表示该操作符为双目运算符 举个例子: 1+2 这里的加号影响了1和2两个操作数,所以"+"就是双目运算符 +1,-1 这里 ...
- 视频画面中实现人脸遮挡教程 - 基于 TensorFlow 实现
在进行视频通话时,我们往往需要对画面进行一些实时分析,例如识别画面里的人.车.动物等等.这节里我们将使用时信魔方的人脸监视模块实现人脸被手部遮挡的检测,如下图所示效果: 预备知识 时信魔方的客户端使用 ...
- Eureka详解系列(一)--先谈谈负载均衡器
这个系列开始研究 Eureka,在此之前,先来谈谈负载均衡器. 本质上,Eureka 就是一个负载均衡器,可能有的人会说,它是一个服务注册中心,用来注册服务的,这种说法不能说错,只是有点片面. 在这篇 ...
- 鸿蒙的多媒体及Menu组件及小程序的多媒体组件
目录: js业务逻辑层 视图渲染层 css属性设置 效果图 微信小程序展示 内网穿透工具下载 我们在搭建一个小程序或者网站的时候,往往要加载很多的图片,音频和视频文件.如果都从服务器获取静态资源,这样 ...
- CSS实现迷你键盘
最近做了一个迷你键盘的dome,这里分享给大家 dome下载地址(点击下载) 代码如下: <!DOCTYPE html> <html lang="en" > ...
- C#+Layui开发后台管理系统
我是笑林新记,分享一下我一套C#开发的后台管理系统,希望对大家有帮助!欢迎关注微信公众号:笑林新记 后台开发语言:C# 前端框架:layui 前天用毛笔笔画制作了一个毛笔字效果的Logo,主 ...
- jQuery 勾选显示
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- Var_init class
1 import org.apache.hadoop.conf.Configuration; 2 import org.apache.hadoop.fs.FSDataInputStream; 3 im ...
- What is the difference between Serialization and Marshaling?
How to serialize and deserialize JSON using C# - .NET | Microsoft Docs https://docs.microsoft.com/en ...