每个线程都有一个ThreadLocalMap对象,ThreadLocalMap是Thread的一个内部类,可以把ThreadLocalMap理解成一个Map,这个Map里存放这一个Thread的所有线程变量。

在我们创建一个线程变量 maxLife 之后,执行其set方法,其实是以maxLife这个对象为键,以0为值,然后将这组键值对放入当前线程的ThreadLocalMap对象中。

如果你不明白这意味着什么,接着往下看。

为了说明ThreadLocal有什么不同,我们直接上代码。

首先,我们在类中定义一个全局变量,后边的所有线程都共享这个变量。

ThreadLocal<Integer> maxLife = null;

然后创建一个线程A,并在这个线程中为maxLife赋一个新对象,并且为其设置值

maxLife = new ThreadLocal<Integer>()
maxLife.set(0);

这个时候让A线程别再往下跑了,同时我们创建一个B线程,然后在B线程里

maxLife = new ThreadLocal<Integer>();

执行完这一段,把B暂停了,然后再回到A线程,执行

Integer i = maxLife.get();

这个时候你如果打印i,那么你会看到一个null。

这是为什么呢?

因为maxLife的get方法,其实是以maxLife这个对象本身为键,然后去当前线程的ThreadLocalMap中获取其所对应的值,A线程中我们new了一个对象然后当成key,B线程中我们又new了一个,我们知道A和B先后new 的两个对象不是同一个对象,那么以不同的对象作为key去一个map里面取值会怎样呢?

也就是说 maxLife 这个变量,在A和B中是共享的,但是maxLife作为key在A和B各自的ThreadLocalMap中对应的值是不一样的,所以我们定义ThreadLocal变量,最好在一开始的时候就为其new一个值,而不是让它等于null。

完毕。

关于ThreadLocal变量的一个坑的更多相关文章

  1. java中变量命名和引用变量的一个坑

    这次有两个主题,第一个太简单啦,就是java中变量的命名规则,纯记忆性东西.第二个主题,就是讨论一下对象引用变量的一个注意点.

  2. 详细领悟ThreadLocal变量

    关于对ThreadLocal变量的理解,我今天查看一下午的博客,自己也写了demo来测试来看自己的理解到底是不是那么回事.从看到博客引出不解,到仔细查看ThreadLocal源码(JDK1.8),我觉 ...

  3. Pyhon环境变量的一些坑

    在正常的情况下,使用编译器执行Python文件,无需考虑环境变量的改变 例:sum --one --one1.py --two --two1.py 在执行one.py文件需要调用 two.py中某个方 ...

  4. ThreadLocal变量

    什么是ThreadLocal变量?ThreadLocal,很多地方叫做线程本地变量,也有些地方叫做线程本地存储,其实意思差不多.可能很多朋友都知道ThreadLocal为变量在每个线程中都创建了一个副 ...

  5. ThreadLocal并不是一个Thread

    ThreadLocal是什么? 早在JDK 1.2的版本中就提供java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一种新的思路.使用这个工具类可以很简洁 ...

  6. vue组件双向绑定.sync修饰符的一个坑

    我们知道组件是单项的,但是有时候需要双向,这时候我们可以使用.sync修饰符,但今天遇到一个坑,一直不成功,花了半小时试出来的.... 在编程的时候我们很习惯冒号后面跟着空格.而.sync双向绑定需要 ...

  7. andriod8.1.0源码编译中的一个坑-package com.sun.javadoc does not exist

    这里记录编译过程中的一个坑!!! 编译过程中出现了下面的报错 external/doclava/src/com/google/doclava/ClassInfo.java:20: error: pac ...

  8. ssh 的一个坑

    概述 今天我碰到 fabric 和 ssh 的一个坑,记录下来,供以后开发时参考,相信对其他人也有用. ssh 今天用 ssh 登录远程服务器用不了 npm,查了下,发现原因是: ssh登录时不会加载 ...

  9. python中Threadlocal变量

    在多线程环境下,每个线程都有自己的数据.一个线程使用自己的局部变量比使用全局变量好,因为局部变量只有线程自己能看见,不会影响其他线程,而全局变量的修改必须加锁. 不加锁就会出现变量会被修改的问题,进而 ...

随机推荐

  1. Web应用扫描测试工具Vega

    Web应用扫描测试工具Vega   Vega是Kali Linux提供的图形化的Web应用扫描和测试平台工具.该工具提供代理和扫描两种模式.在代理模式中,安全人员可以分析Web应用的会话信息.通过工具 ...

  2. J2EE并发策略控制总结[zz]

    本文结合hibernate以及JPA标准,对J2EE当前持久层设计所遇到的几个问题进行总结: 第一:事务并发访问控制策略    当前J2EE项目中,面临的一个共同问题就是如果控制事务的并发访问,虽然有 ...

  3. [Lydsy1806月赛] 最长公共子序列

    首先可以证明,只由一种字符构成的串总会是最优解中的一种... 考虑随便一个T与S的LIS都至少是出现次数最少的字符个数(考虑反证法,如果要更短,那么T中每种字符的个数都至多是 S 中最少的字符个数-1 ...

  4. 【贪心】【set】zoj3963 Heap Partition

    贪心地从前往后扫,每到一个元素,就查看之前的元素中小于等于其的最大的元素是否存在,如果存在,就将它置为其父亲.如果一个结点已经是两个儿子的父亲了,就不能在set中存在了,就将他删除.如果然后将当前元素 ...

  5. PS 2019 | Photoshop CC 2019 的安装激活

    文章目录 写在前面 安装步骤 软件激活 关闭"主页"屏幕 写在前面 Photoshop CC 2019(64位)下载地址: 链接:https://pan.baidu.com/s/1 ...

  6. 【Data URL】【RE】【bugku】逆向入门writeup

    在写wp之前先来了解一下Data URL是什么 Data URL 在浏览器向服务端发送请求来引用资源时,一般浏览器都有同一时间并发请求数不超过4个的限制.所以如果一个网页需要引用大量的服务端资源,就会 ...

  7. [转][Navicat for MySQL系列]Navicat如何使用(二)

    上一篇经验已经建立了数据连接,这篇我介绍一下Navicat for MySQL的“增删改查”功能是如何操作的. 工具/原料 Navicat for MySQL 10.1.7 数据库操作(基本) 1 远 ...

  8. mysql备份相关

    1linux下mysql导出文件 备份mysql数据库的命令 mysqldump -h主机名 -u用户名 -p密码 数据库名字 > 备份的数据库名字.sql 例如:mysqldump  -uro ...

  9. bash中的管道和重定向

    管道 管道命令操作符是:”|”,它仅能处理经由前面一个指令传出的正确输出信息,也就是 standard output 的信息,对于 stdandarderror 信息没有直接处理能力.然后,传递给下一 ...

  10. 在代码中加载storyBoard中的ViewController

    首先, 要在storyBoard中画出想要的VC, 然后建一个VC类和他关联.如图 : 调用时找如下写: DetailViewController *detailVC = [[UIStoryboard ...