ThreadLocal详解(实现多线程同步访问变量)

ThreadLocal翻译成中文比较准确的叫法应该是:线程局部变量。

  这个玩意有什么用处,或者说为什么要有这么一个东东?先解释一下,在并发编程的时候,成员变量如果不做任何处理其实是线程不安全的,各个线程都 在操作同一个变量,显然是不行的,并且我们也知道volatile这个关键字也是不能保证线程安全的。那么在有一种情况之下,我们需要满足这样一个条件: 变量是同一个,但是每个线程都使用同一个初始值,也就是使用同一个变量的一个新的副本。这种情况之下ThreadLocal就非常使用,比如说DAO的数 据库连接,我们知道DAO是单例的,那么他的属性Connection就不是一个线程安全的变量。而我们每个线程都需要使用他,并且各自使用各自的。这种 情况,ThreadLocal就比较好的解决了这个问题。

  我们从源码的角度来分析这个问题。

  首先定义一个ThreadLocal:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class ConnectionUtil {
    private static ThreadLocal<Connection> tl = new ThreadLocal<Connection>();
    private static Connection initConn = null;
    static {
        try {
            initConn = DriverManager.getConnection("url, name and password");
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
     
    public Connection getConn() {
        Connection c = tl.get();
        tl.set(initConn);
        return c;
    }
     
}

  这样子,都是用同一个连接,但是每个连接都是新的,是同一个连接的副本。

  那么实现机制是如何的呢?

  1、每个Thread对象内部都维护了一个ThreadLocalMap这样一个ThreadLocal的Map,可以存放若干个ThreadLocal。

1
2
3
/* ThreadLocal values pertaining to this thread. This map is maintained
 * by the ThreadLocal class. */
ThreadLocal.ThreadLocalMap threadLocals = null;

  2、当我们在调用get()方法的时候,先获取当前线程,然后获取到当前线程的ThreadLocalMap对象,如果非空,那么取出ThreadLocal的value,否则进行初始化,初始化就是将initialValue的值set到ThreadLocal中。

1
2
3
4
5
6
7
8
9
10
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();
}

  3、当我们调用set()方法的时候,很常规,就是将值设置进ThreadLocal中。

  4、总结:当我们调用get方法的时候,其实每个当前线程中都有一个ThreadLocal。每次获取或者设置都是对该ThreadLocal进行的操作,是与其他线程分开的。

  5、应用场景:当很多线程需要多次使用同一个对象,并且需要该对象具有相同初始化值的时候最适合使用ThreadLocal。

  6、其实说再多也不如看一下源码来得清晰。如果要看源码,其中涉及到一个WeakReference和一个Map,这两个地方需要了解下,这两 个东西分别是a.Java的弱引用,也就是GC的时候会销毁该引用所包裹(引用)的对象,这个threadLocal作为key可能被销毁,但是只要我们 定义成他的类不卸载,tl这个强引用就始终引用着这个ThreadLocal的,永远不会被gc掉。b.和HashMap差不多。

  事实上,从本质来讲,就是每个线程都维护了一个map,而这个map的key就是threadLocal,而值就是我们set的那个值,每次线 程在get的时候,都从自己的变量中取值,既然从自己的变量中取值,那肯定就不存在线程安全问题,总体来讲,ThreadLocal这个变量的状态根本没 有发生变化,他仅仅是充当一个key的角色,另外提供给每一个线程一个初始值。如果允许的话,我们自己就能实现一个这样的功能,只不过恰好JDK就已经帮 我们做了这个事情。

转载于:https://www.cnblogs.com/Berryxiong/p/6220545.html

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

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

相关文章

SCREEN屏幕编程时候必须保证SCREN中词典的字段格式必须和数据表中字段的类型长度一致!...

此时任意操作都会出现如下问题 /h调试 回车调试被激活任意操作 执行到第23行时候报错“请输入一个数值”&#xff0c;检查数据表中字段参考数据元素以及对应的域均是char类型&#xff0c;此时检查screen屏幕设置字段类型&#xff0c;/n退出程序 重新进入程序 单击 点击屏幕9000…

mysql 阿里云 版本_关于阿里云centos版本,mysql5.7的一些注意事项

1.阿里云进去mysql是默认已经安装好了的&#xff0c;只需要修改root用户的密码。关于修改密码&#xff1a;1)登陆阿里云&#xff0c;进入root目录&#xff0c;会有mysql的.sh文件&#xff0c;可以通过运行该文件得到初始密码。此时用初始密码登陆mysql&#xff0c;use mysql 切…

JAXB –不需要注释

似乎存在一个误解&#xff0c;认为在模型上需要使用批注才能使用JAXB&#xff08;JSR-222&#xff09;实现。 事实是&#xff0c;JAXB是例外配置&#xff0c;因此仅当您要覆盖默认行为时才需要注释。 在此示例中&#xff0c;我将演示如何在不提供任何元数据的情况下使用JAXB。 …

zabbix 3.0.3 (nginx)安装过程中的问题排错记录

特殊注明&#xff1a;安装zabbix 2.4.8和2.4.6遇到2个问题&#xff0c;如下&#xff1a;找了很多解决办法&#xff0c;实在无解&#xff0c;只能换版本&#xff0c;尝试换&#xff08;2.2.2正常 | 3.0.3正常&#xff09;都正常&#xff0c;最后决定换3.0.31、Error connecting …

安装mysql5.7.24rpm_centos7安装mysql-5.7.24(rpm安装)

关于mysql的4个rpm包node[rootelk-200 ~]# ls mysql/ -lhtotal 192M-rw-r--r-- 1 root root 25M Aug 26 12:38 mysql-community-client-5.7.24-1.el7.x86_64.rpm-rw-r--r-- 1 root root 275K Aug 26 12:38 mysql-community-common-5.7.24-1.el7.x86_64.rpm-rw-r--r-- 1 root ro…

Java锁实现

我们都使用第三方库作为开发的正常部分。 通常&#xff0c;我们无法控制其内部。 JDK随附的库是一个典型示例。 这些库中的许多库都使用锁来管理竞争。 JDK锁具有两种实现。 人们使用原子CAS样式指令来管理索赔过程。 CAS指令往往是最昂贵的CPU指令类型&#xff0c;并且在x86上…

一键生成APP官网

只需要输入苹果下载地址&#xff0c;安卓市场下载地址&#xff0c;或者内测下载地址&#xff0c;就能一键生成APP的官网&#xff0c;方便在网上推广。 好推APP官网 www.hotapp.cn/app 转载于:https://www.cnblogs.com/likwo/p/6223889.html

python 字符ab+字符c 2_“ab”+”c”*2 结果是: (1.3分)_学小易找答案

【判断题】药物效应动力学简称药效学,是研究药物对机体的作用?【单选题】以下关于Python语言中“缩进”说法正确的是:‪‬‪‬‪‬‪‬‪‬‮‬‭‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‪‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪‬‪‬‪‬‪…

数据结构及算法 -- 目录

排序算法 -- 目录 啦啦啦转载于:https://www.cnblogs.com/ClassNotFoundException/p/7122848.html

Spring MVC集成测试

在Spring MVC中对控制器进行集成测试的一种方法是使用Spring提供的集成测试支持。 对于Junit4&#xff0c;此支持包括一个名为SpringJunit4ClassRunner的自定义Junit Runner和一个用于加载相关Spring配置的自定义批注。 样本集成测试将遵循以下原则&#xff1a; RunWith(Spri…

spark 快速入门 java API

Spark的核心就是RDD&#xff0c;对SPARK的使用入门也就是对RDD的使用&#xff0c;包括action和transformation 对于Java的开发者&#xff0c;单单看文档根本是没有办法理解每个API的作用的&#xff0c;所以每个SPARK的新手&#xff0c;最好按部就班直接学习scale, 那才是一个高…

网页设计上机考试原题_Dreamweaver上机考试题目dreamweaver试题库网页制作试题.doc...

网页设计上机考试题集注意&#xff1a;所有题目中涉及的素材都在考试文件夹内&#xff0c;其中图片在下面的pic文件夹中&#xff0c;音乐、flash在media文件夹。1) 在1.html中的顶部添加一个锚点链接&#xff0c;点击之能立即到达页面最底端。2) 将1.html中的所有链接的默认样式…

35数据结构与算法分析之---最短路径

本系列是阅读《数据结构与算法应用实践教程》第2版 主编 李文书 北京大学出版社 的读书笔记&#xff0c;加上自己的理解&#xff0c;更多的是学习的记录与反思&#xff0c;如有不妥&#xff0c;欢迎指正&#xff0c;非常感谢。转载于:https://www.cnblogs.com/guochaoxxl/p/712…

Quartz 2 Scheduler示例

Quartz是一个开源作业调度框架。 它可用于管理和计划应用程序中的作业。 步骤1&#xff1a;建立已完成的专案 创建一个Maven项目&#xff0c;如下所示。 &#xff08;可以使用Maven或IDE插件来创建它&#xff09;。 步骤2&#xff1a;图书馆 Quartz依赖项已添加到Maven的po…

sql server 2008 com.microsoft.sqlserver.jdbc.SQLServerException: 通过端口 1433 连接到主机

原内容搬迁到了新网站&#xff0c;给你带来的不便&#xff0c;敬请谅解&#xff01; 》 http://www.suanliutudousi.com/2017/08/28/sql-server-2008-com-microsoft-sqlserver-jdbc-sqlserverexception-%E9%80%9A%E8%BF%87%E7%AB%AF%E5%8F%A3-1433-%E8%BF%9E%E6%8E%A5%E5%88%B0…

如何通过网线连接两台电脑快速传输数据?

介绍 我们经常需要拷贝文件会用到类似U盘等工具&#xff0c;但我们有时在传输大文件时又苦于没有&#xff0c;那么大内存的转存工具。这时候我们就可以通过一条小小的网线连接两台电脑&#xff0c;形成一个小的局域网传输数据&#xff0c;因为是通过网线传输&#xff0c;所以传…

30分钟内使用MongoDB

最近&#xff0c;我被NoSQL错误咬住了-或是我的同事Mark Atwell提出的“燃烧在哪里&#xff01;” 运动。 尽管我无意于在不久的将来或可预见的将来回避友好的“ SELECT ... WHERE”&#xff0c;但我确实设法弄懂了一些代码。 在本文中&#xff0c;我分享了我在NoSQL世界中首次…

【Django】--ModelForm组件

ModelForm a.class Meta:model,#对应Model的  fieldsNone,#字段  excludeNone,#排除字段  labelsNone,#提示信息  help_texts None,#帮助提示信息  widgets None,#自定义插件  error_messages None,#自定义错误信息(整体错误信息from django.core.exceptions im…

mysql实际综合案例_Mysql综合案例

Mysql综合案例考核要点&#xff1a;创建数据表、单表查询、多表查询已知&#xff0c;有一个学生表student和一个分数表score&#xff0c;请按要求对这两个表进行操作。student表和score分数表的表结构分别如表1-1和表1-2所示。表1-1student表结构字段名数据类型主键外键非空唯一…

2012年I / O之后

从注册到赠品&#xff0c;每年的I / O疯狂都在不断发展。 在今年20分钟内被出售&#xff0c;并没有阻止Google赠送更多的东西。 以这种速度并有望在明年发布Google Glass&#xff0c;明年注册很可能会变得更加混乱&#xff01; 因此&#xff0c;Google&#xff0c;请停止提供免…