Java并发编程实战~ThreadLocal

ThreadLocal 的使用方法

static class SafeDateFormat {// 定义 ThreadLocal 变量static final ThreadLocal<DateFormat>tl = ThreadLocal.withInitial(()-> new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));static DateFormat get(){return tl.get();}
}// 不同线程执行下面代码
// 返回的 df 是不同的
DateFormat df = SafeDateFormat.get();

ThreadLocal 的工作原理

错误的实现方案

 

class MyThreadLocal<T> {Map<Thread, T> locals = new ConcurrentHashMap<>();// 获取线程变量 T get() {return locals.get(Thread.currentThread());}// 设置线程变量void set(T t) {locals.put(Thread.currentThread(), t);}
}

JDK实现方案

        Thread 这个类内部有一个私有属性 threadLocals,其类型就是 ThreadLocalMap,ThreadLocalMap 的 Key 是ThreadLocal。

 

class Thread {// 内部持有 ThreadLocalMapThreadLocal.ThreadLocalMap threadLocals;
}class ThreadLocal<T>{public T get() {// 首先获取线程持有的//ThreadLocalMapThreadLocalMap map = Thread.currentThread().threadLocals;// 在 ThreadLocalMap 中// 查找变量Entry e = map.getEntry(this);return e.value; }static class ThreadLocalMap{// 内部是数组而不是 MapEntry[] table;// 根据 ThreadLocal 查找 EntryEntry getEntry(ThreadLocal key){// 省略查找逻辑}//Entry 定义static class Entry extends WeakReference<ThreadLocal>{Object value;}}
}

        ThreadLocal 仅仅是一个代理工具类,内部并不持有任何与线程相关的数据,所有和线程相关的数据都存储在 Thread 里面,这样的设计容易理解。而从数据的亲缘性上来讲,ThreadLocalMap 属于 Thread 也更加合理。

        当然还有一个更加深层次的原因,那就是不容易产生内存泄露。在我们的设计方案中,ThreadLocal 持有的 Map 会持有 Thread 对象的引用,这就意味着,只要 ThreadLocal对象存在,那么 Map 中的 Thread 对象就永远不会被回收。ThreadLocal 的生命周期往往都比线程要长,所以这种设计方案很容易导致内存泄露。而 Java 的实现中 Thread 持有ThreadLocalMap,而且 ThreadLocalMap 里对 ThreadLocal 的引用还是弱引用(WeakReference),所以只要 Thread 象可以被回收,那么 ThreadLocalMap 就能被回收。Java 的这种实现方案虽然看上去复杂一些,但是更加安全。

ThreadLocal 与内存泄露

        在线程池中使用 ThreadLocal 为什么可能导致内存泄露呢?原因就出在线程池中线程的存活时间太长,往往都是和程序同生共死的,这就意味着 Thread 持有的 ThreadLocalMap一直都不会被回收,再加上 ThreadLocalMap 中的 Entry 对 ThreadLocal 是弱引用(WeakReference),所以只要 ThreadLocal 结束了自己的生命周期是可以被回收掉的。但是 Entry 中的 Value 却是被 Entry 强引用的,所以即便 Value 的生命周期结束了,Value 也是无法被回收的,从而导致内存泄露。

        那在线程池中,我们该如何正确使用 ThreadLocal 呢?其实很简单,既然 JVM 不能做到自动释放对 Value 的强引用,那我们手动释放就可以了。

ExecutorService es;
ThreadLocal tl;
es.execute(()->{//ThreadLocal 增加变量tl.set(obj);try {// 省略业务逻辑代码}finally {// 手动清理 ThreadLocal tl.remove();}
});

InheritableThreadLocal 与继承性

        通过 ThreadLocal 创建的线程变量,其子线程是无法继承的。也就是说你在线程中通过
ThreadLocal 创建了线程变量 V,而后该线程创建了子线程,你在子线程中是无法通过
ThreadLocal 来访问父线程的线程变量 V 的。

        如果你需要子线程继承父线程的线程变量,那该怎么办呢?其实很简单,Java 提供了
InheritableThreadLocal 来支持这种特性。

        不过,不建议你在线程池中使用 InheritableThreadLocal,不仅仅是因为它具有ThreadLocal 相同的缺点——可能导致内存泄露,更重要的原因是:线程池中线程的创建是动态的,很容易导致继承关系错乱,如果你的业务逻辑依赖 InheritableThreadLocal,那么很可能导致业务逻辑计算错误,而这个错误往往比内存泄露更要命。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/496700.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

智慧停车介绍、产业链市场全透析

来源&#xff1a;传感器技术最近&#xff0c;Goodwin调查发现&#xff0c;在城市地区&#xff0c;接近30%的交通拥堵源自于司机寻找停车位。据称&#xff0c;到2020年&#xff0c;将会有20亿的汽车在公路上跑着&#xff0c;这就意味着&#xff0c;届时汽车的数量将比目前多了7.…

Python 下载 图片、音乐、视频 和 断点续传

Python3 使用 requests 模块显示下载进度: http://blog.csdn.net/supercooly/article/details/51046561 python编写断点续传下载软件&#xff1a;https://www.leavesongs.com/PYTHON/resume-download-from-break-point-tool-by-python.html Python实现下载界面(带进度条&…

10停止nginx命令 win_Linux下配置Nginx并使用https协议

环境Centos7.6nginx-1.17.0下载官网&#xff1a;http://nginx.org/download/nginx-1.17.0.tar.gz环境确认在安装nginx前首先要确认系统中是否安装gcc、pcre-devel、zlib-devel、openssl-devel检查是否安装过软件包yum list installed | grep xxx安装软件包yum -y install gcc p…

腾讯AI Lab发布三大核心战略,与自然科研达成战略合作

来源&#xff1a;腾讯AI实验室3月15日&#xff0c;腾讯AI Lab第二届学术论坛在深圳举行&#xff0c;聚焦人工智能在医疗、游戏、多媒体内容、人机交互等四大领域的跨界研究与应用。全球30位顶级AI专家出席&#xff0c;对多项前沿研究成果进行了深入探讨与交流。本次论坛以“共享…

Java并发编程实战~Guarded Suspension模式

Guarded Suspension 模式 比如&#xff0c;项目组团建要外出聚餐&#xff0c;我们提前预订了一个包间&#xff0c;然后兴冲冲地奔过去&#xff0c;到那儿后大堂经理看了一眼包间&#xff0c;发现服务员正在收拾&#xff0c;就会告诉我们&#xff1a;“您预订的包间服务员正在收…

diy直立双足机器人_Aelos Pro 机器人:让编程变得更有趣

前言拥有一台酷炫的机器人是每个人儿时的梦想&#xff0c;爱搞机最近也有机会拿到一款来自乐聚的新品&#xff1a; Aelos Pro 机器人。相信有了解过机器人的朋友&#xff0c;应该对乐聚有所耳闻&#xff0c;乐聚在人形机器人领域一直都是行业的佼佼者&#xff0c;Aelos 系列机器…

中国科学家首次解析人脑“中央处理器”,领先美国脑计划

来源&#xff1a;澎湃新闻 作者&#xff1a;贺梨萍“我们可以探索数光年外的宇宙&#xff0c;但对我们两耳之间3磅重的大脑知之甚少。”这一想法推动美国前任总统奥巴马启动了“推进创新神经技术脑研究计划”&#xff0c;也就是所谓的 “脑计划”。中国同一领域内的研究也在加…

物理拓扑和逻辑拓扑——现实和应用的比较

在每一个网络管理者的脑子里几乎都有一张自己所管理的网络拓扑图。在网管系统中&#xff0c;生成拓扑图是网管系统的基本功能之一。目前&#xff0c;在网管系统中生成的的拓扑图分为物理拓扑和逻辑拓扑&#xff0c;他们有什么不同呢&#xff1f; 作为网络的管理者我们知道&…

虚拟机无法接受组播消息_IPTV(组播)骨干网完整解决方案--四川广电网络

一&#xff0c;基于ANYCAST 设计骨干RP热备1&#xff0c;RP选举说明组播网络RP设置分为动态&#xff0c;静态2种。但和很多网络协议不一样&#xff0c;RP的选择默认是动态优先。也就是在路由器上同时存在动态和静态RP的时候会优选动态&#xff0c;除非定义强制静态优选动态才不…

Java并发编程实战~Worker Thread模式

在上一篇文章中&#xff0c;我们介绍了一种最简单的分工模式——Thread-Per-Message 模式&#xff0c;对应到现实世界&#xff0c;其实就是委托代办。这种分工模式如果用 Java Thread 实现&#xff0c;频繁地创建、销毁线程非常影响性能&#xff0c;同时无限制地创建线程还可能…

DES算法

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录前言一、DES是什么&#xff1f;二、go语言实现1.使用CBC模式1.使用ECB模式前言 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、DES是什…

2018年世界前沿科技趋势展望及2017年态势总结

来源&#xff1a;全球技术地图本文以智能制造、新材料和信息三大领域为例&#xff0c;深入浅出的探讨了2017年以来世界前沿科技的发展脉络&#xff0c;并对2018年可能的走势进行了预测。-智能制造领域-2017年态势总结多国推出新举措&#xff0c;推动先进制造发展美国成立白宫贸…

写给女友的情诗

亲爱抱抱每次看到你很快乐的样子总是让我无比欢畅你让我看到幸福 让我看到阳光彼此的那份甜蜜只有你我才能感觉得到你让我忘掉悠愁 让我忘掉烦恼你就是我最闪亮的星星亲爱的让我紧紧的抱抱每次都是那么地不一样无论如何我还是喜欢这样抱着你直到永远Hei Baby You are my favori…

机器人3·15 | 赛迪「机器人国评中心」揭示机器人产品质量6大痛点!

来源&#xff1a;雷克世界机器人是“制造业皇冠顶端的明珠”&#xff0c;其研发、制造、应用是衡量一个国家科技创新和高端制造业水平的重要标志。当前&#xff0c;我国机器人市场进入高速增长期&#xff0c;“机器换人”浪潮势不可挡&#xff0c;产品应用层见叠出&#xff0c;…

jq如何在打开新的页面 关闭之前同链接的页面_教你如何“抢”其他域名的权重...

白帽波哥的上一篇文章《这三种域名&#xff0c;永远不会有询盘》里留了两个尾巴&#xff0c;一个是如何将好域名的权重导到一个新域名上&#xff0c;另一个是如何清除域名里的垃圾外链。今天先讲第一个&#xff0c;如何将好的老域名权重导到新域名&#xff0c;也就是业内常说的…

ARM GIC (五)gicv3架构-LPI

在gicv3中,引入了一种新的中断类型。message based interrupts,消息中断。 一、消息中断 外设,不在通过专用中断线,向gic发送中断,而是写gic的寄存器,来发送中断。 这样的一个好处是,可以减少中断线的个数。 为了支持消息中断,gicv3,增加了LPI,来支持消息中断。并且…

全球自动驾驶汽车发展指数哪家强?美德领衔,中国第七

来源&#xff1a;新智驾近日&#xff0c;罗兰贝格与德国著名汽车研究机构亚琛汽车工程技术有限公司共同发布《2017年第四季度全球自动驾驶汽车发展指数》报告&#xff0c;基于行业和市场两个维度&#xff0c;对全球主要汽车大国在自动驾驶领域的竞争态势做出全面比较。其中“行…

笔记:数据绑定表达式(一)

数据绑定表达式必须包含在<%#和%>字符之间。格式如下: <tagprefix:tagname property<%# data-binding expression %> runat"server" />或者如下&#xff1a; <%# data-binding expression %> ASP.NET 支持分层数据绑定模型&#xff0c;数据绑…

Java并发编程实战~Thread-Per-Message模式

我们曾经把并发编程领域的问题总结为三个核心问题&#xff1a;分工、同步和互斥。其中&#xff0c;同步和互斥相关问题更多地源自微观&#xff0c;而分工问题则是源自宏观。我们解决问题&#xff0c;往往都是从宏观入手&#xff0c;在编程领域&#xff0c;软件的设计过程也是先…

水面反光如何拍摄_如何在雨中拍摄,这些技巧会让你的摄影更完美

雨是柔弱的&#xff0c;是世界上最轻灵的东西&#xff0c;敲不响那钢筋水泥造的高楼。而瓦屋则不同&#xff0c;雨滴在上面&#xff0c;叮叮当当的&#xff0c;立即奏出悦耳的声音。身在小屋的人也就有了在雨中亲近自然的福气。而且在雨天睡觉是最舒服的了~在阴雨天气中最熟悉的…