实现threadlocal_ThreadLocal如何实现?

实现threadlocal

这是我上周的帖子的后续文章,其中我解释了ThreadLocal用法背后的动机 。 从帖子中我们可以回忆起,如果您希望为每个线程拥有一个独立初始化的变量副本,则ThreadLocal确实是一个很酷的概念。 现在,好奇的人可能已经开始问“我如何在Java中实现这样的概念”?

否则,您可能会觉得这不是一个有趣的话题–毕竟,您在这里所需的只是一张地图 ,不是吗? 在处理ThreadLocal <T>时 ,将解决方案实现为HashMap <Thread,T>并以Thread.currentThread()为键似乎是明智的选择。 其实不是那么简单。 因此,如果您有五分钟的时间,请忍受我,我将指导您完成一个漂亮的设计概念。

简单的HashMap解决方案的第一个明显问题是线程安全性。 由于HashMap并不是为支持并发使用而构建的,因此我们无法在多线程环境中安全地使用该实现。 幸运的是,我们不需要花很多时间来解决问题-ConcurrentHashMap <Thread,T>看起来像是天作之合。 检索的完全并发性和可调整的预期更新并发性正是我们首先需要的。

现在,如果您将基于ConcurrentHashMap的解决方案应用于JDK源代码中的ThreadLocal实现,则会带来两个严重的问题。

  • 首先,在Map结构中将线程作为键。 由于该映射永远不会被垃圾回收,因此最终您将永远保持对该线程的引用,从而阻止该线程成为GCd。 不情愿的是,您在设计中造成了巨大的内存泄漏。
  • 第二个问题可能需要更长的时间才能浮出水面,但是即使在幕后进行了巧妙的分段以减少锁争用的机会, ConcurrentHashMap仍然承担同步开销。 在同步需求仍然存在的情况下,您仍然拥有一个结构,可能成为瓶颈的根源。

但是,让我们首先开始解决最大的问题。 如果我们的引用是指向相关线程的最后一个引用,则我们的数据结构需要允许对线程进行垃圾回收。 再次,第一个可能的解决方案是盯着我们看-为什么不使用WeakReferences代替我们通常对对象的引用 ? 因此,实现现在看起来类似于以下内容:

Collections.synchronizedMap(new WeakHashMap<Thread, T>())

现在,我们已经解决了泄漏问题–如果除我们之外没有人引用Thread ,则可以将其定型并进行垃圾回收。 但是我们仍然没有解决并发问题。 现在,解决方案实际上是关于跳出思路思考的样本。 到目前为止,我们已经将ThreadLocal变量视为映射到变量的Threads 。 但是,如果我们颠倒了思路,而是设想了一个解决方案,将ThreadLocal对象映射到每个Thread中的值,该怎么办? 如果每个线程都存储该映射,并且ThreadLocal只是该映射的接口,则可以避免同步问题。 更好的是,我们还避免了GC带来的问题!

确实,当我们打开ThreadLocalThread类的源代码时 ,我们看到这正是在JDK中实际实现该解决方案的方式:

public class Thread implements Runnable {ThreadLocal.ThreadLocalMap threadLocals = null;// cut for brevity
}
public class ThreadLocal<T> {static class ThreadLocalMap {// cut for brevity}ThreadLocalMap getMap(Thread t) {return t.threadLocals;}public T get() {Thread t = Thread.currentThread();ThreadLocalMap map = getMap(t);if (map != null) {ThreadLocalMap.Entry e = map.getEntry(this);if (e != null)return (T) e.value;}return setInitialValue();}private T setInitialValue() {T value = initialValue();Thread t = Thread.currentThread();ThreadLocalMap map = getMap(t);if (map != null)map.set(this, value);elsecreateMap(t, value);return value;}// cut for brevity
}

所以我们在这里。 Thread类保留对ThreadLocal.ThreadLocalMap实例的引用,该实例是使用对键的弱引用构建的。 以相反的方式构建结构,由于ThreadLocal只能访问当前线程中的值,因此完全避免了线程争用问题。 另外,当Thread完成工作时,映射可以进行垃圾回收,因此我们还避免了内存泄漏问题。

希望您对设计有所了解,因为它确实是解决复杂问题的理想解决方案。 我确实认为阅读源代码是学习新概念的理想方式。 而且,如果您是Java开发人员,那么,比阅读Joshua Bloch和Doug Lea集成到JDK的源代码更好的地方是获得知识的地方?

参考: 如何实现ThreadLocal? 由我们的JCG合作伙伴 Nikita Salnikov Tarnovski在Plumbr Blog博客上获得。

翻译自: https://www.javacodegeeks.com/2013/11/how-is-threadlocal-implemented.html

实现threadlocal

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

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

相关文章

mysql timeout的单位_mysql的timeout-阿里云开发者社区

mysql的timeout很多时候我们连接mysql会在timeout这里跌倒&#xff0c;这里明确下mysql的timeout&#xff1a;下面是获取timeout的变量&#xff1a;mysql> show global variables like "%timeout%";---------------------------------------| Variable_name | Val…

带有Spring Boot 2.0的Spring Security:UserDetailsS​​ervice

正如我们在上一篇文章中所看到的&#xff0c;我们的spring应用程序的用户名和密码是通过环境变量配置的。 这对于原型目的是可以的&#xff0c;但是在现实生活中&#xff0c;我们必须提供另一种方式来使用户有资格登录到该应用程序。 为此&#xff0c;我们使用UserDetailsS​​…

java计算整数出现的次数_[剑指offer题解][Java]1到n整数中1出现的次数

前言众所周知&#xff0c;《剑指offer》是一本“好书”。如果你是个算法菜鸡&#xff08;和我一样&#xff09;&#xff0c;那么最推荐的是先把剑指offer的题目搞明白。对于剑指offer题解这个系列&#xff0c;我的写作思路是&#xff0c;对于看过文章的读者&#xff0c;能够做到…

mysql数据库+ssh框架_SSH框架+Mysql数据库开发java web会员积分消费管理系统

项目描述会员消费管理&#xff1a;会员信息调取查询、会员消费商品添加金额计算、兑换商品等会员管理&#xff1a;会员增删改查积分管理&#xff1a;积分设置、商品积分设置等积分兑换、数据库备份还原、折扣管理、商品管理等运行环境jdk7(8)tomcat7(8)mysql5.7myeclipes或ecli…

spring和spring_Spring交易可见性

spring和spring在初始化应用程序上下文时&#xff0c;Spring在遇到带有Transactional标记的类时会创建代理。 Transactional可以应用于类级别或方法级别。 在类级别应用它意味着该类中定义的所有公共方法都是事务性的。 Spring创建的代理类型&#xff0c;即Jdk代理或CGLIB代理&…

python上传文件到linux服务器_python上传大文件到服务器报错

项目需要&#xff0c;在mac上将打包好的文件(四五百兆)自动上传到web后台&#xff0c;用了两种方式上传&#xff0c;都报了类似的错误&#xff0c;在windows和linux上测试不会报错&#xff0c;但是到了mac打包机上就会报错&#xff1a;①第一种报错&#xff1a;Traceback (most…

mysql 更改root密码及 主机_设置更改root密码(远程,本地)、连接mysql、mysql常用命令...

设置更改root密码1、将mysql加入环境变量中[rootcentos7 ~]# grep mysql /etc/profileexport PATH/usr/local/mysql/bin/:$PATH2、直接登录&#xff0c;无密码[rootcentos7 ~]# mysql -uroot3、方式一&#xff1a;设置密码[rootcentos7 ~]# mysqladmin -uroot password 123456W…

从NetBeans运行和调试WildFly Swarm应用程序

使用NetBeans的Java EE开发人员习惯于直接在NetBeans所选择的应用程序服务器中运行和调试其瘦战应用程序。 在开发打包为ber或镂空jars的微服务时&#xff0c;您期望使用相同的轻松方式进行运行和调试。 好消息是您可以。 在本文中&#xff0c;我将逐步演示如何在NetBeans中运行…

mysql 事实表 维度表_数据库的事实表与维度表

维度表示你要对数据进行分析时所用的一个量&#xff0c;比如你要分析产品销售情况&#xff0c;你可以选择按类别来进行分析&#xff0c;或按区域来分析&#xff0c;这样的按照什么分析就构成一个维度。前面的实例就可以有两个维度&#xff1a;类型和区域。另外每个维度还可以有…

hazelcast入门教程_Hazelcast入门

hazelcast入门教程7月&#xff0c;我写了一个博客向Java开发人员介绍erlang&#xff0c;重点介绍了这两种语言之间的一些异同。 erlang虚拟机具有许多令人印象深刻的内置功能&#xff0c;其中之一是它们独立于位置且可以相互通信。 这意味着可以通过编写很少的代码行在VM之间同…

tcp java实例_实现了基于TCP的Java Socket编程实例代码

实现了基于TCP的Java Socket编程&#xff0c;功能很简单&#xff1a;客户端向服务器端输出一名话"connect"&#xff0c;服务器端接收输出到控制台并向客户端输出一名话"Hello",客户端接收并输出。1.服务器端package javase.net.socket;import java.io.Data…

java 批量上传图片插件_java多文件上传plupload控件实现多图片上传(一)

使用的是plupload-2.1.2 控件。网上资源挺多的&#xff0c;很好下载。plupload 官方地址 : http://www.plupload.com/plupload 示例: http://www.plupload.com/examples/plupload Github: https://github.com/moxiecode/plupload整体框架用的是easyui springMVC。1、前台jsp页…

java servlet_Java Servlet的前100个问题

java servlet1&#xff09;是“ servlets”目录还是“ servlet”目录&#xff1f; 回答&#xff1a; 对于Java Web Server&#xff1a; 在文件系统上&#xff0c;它是“ servlet” c&#xff1a;\ JavaWebServer1.1 \ servlets \ DateServlet.class 在URL路径中&#xff0c;…

精通java ee项目案例_精通JavaEE项目案例

第1章 Java EE开发入门 11.1 基本概念 11.1.1 Java EE API 11.1.2 MVC模型 21.1.3 JSP讨论 31.1.4 Servlet讨论 41.1.5 Model1和Model2 51.2 Eclipse 51.2.1 Eclipse的平台简介 61.2.2 Eclipse的体系结构 61.3 Struts 71.3.1 认识Struts 71.3.2 Strut…

java调用php session_php读取memcahed java session

情景&#xff1a;1&#xff1a;现在有两个系统&#xff0c;一个是Java做的系统&#xff0c;一个是PHP的系统&#xff0c;现在要把两个系统弄成一个单点登录。2&#xff1a;两个系统两个库&#xff0c;两个库的表结构完全不同&#xff0c;现在要解决的就是session共享问题和用户…

[MEGA DEAL]完整的Java编程训练营(94%折扣)

成为Java Master的10门课程&#xff08;83.5小时&#xff09;&#xff1a;使用JavaFX的设计UI&#xff0c;利用设计模式&#xff0c;Master Multithreading等 嘿&#xff0c;怪胎&#xff0c; 本周&#xff0c;在我们的JCG Deals商店中 &#xff0c;我们提供了另一个超值优惠…

怎么把java程序放进php_如何在php脚本中执行Java程序?

I have been struggling with this for awhile trying all sorts of options withno results – the file is never created(the file is created with an absolutepath so it’s not being created and Ijust can’t find the file). Does anyonehave any ideas?我认为问题是…

java重排序_Java内存模型FAQ(四)重排序意味着什么?

译者&#xff1a;Alex在很多情况下&#xff0c;访问一个程序变量(对象实例字段&#xff0c;类静态字段和数组元素)可能会使用不同的顺序执行&#xff0c;而不是程序语义所指定的顺序执行。编译器能够自由的以优化的名义去改变指令顺序。在特定的环境下&#xff0c;处理器可能会…

javafx响应式布局_JavaFX的响应式设计

javafx响应式布局使用CSS技术&#xff0c;为您的网站创建响应式设计相对容易。 根据屏幕的大小&#xff0c;您可以使用其他CSS文件和布局。 在JavaFX中&#xff0c;乍一看似乎有些困难&#xff0c;因为CSS仅负责样式&#xff0c;而不负责布局。 但是&#xff0c;为各个屏幕尺寸…

pojo java_什么是POJO,JavaBean?

什么是POJO&#xff0c;JavaBean&#xff1f;总结&#xff1a;POJO&#xff1a;一个简单的Java类&#xff0c;这个类没有实现/继承任何特殊的java接口或者类&#xff0c;不遵循任何主要java模型&#xff0c;约定或者框架的java对象。在理想情况下&#xff0c;POJO不应该有注解。…