ThreadLocal是什么?
    ThreadLocal是用来维护线程中的变量不被其他线程干扰而出现的一个结构,内部包含一个ThreadLocalMap类,该类为Thread类的一个局部变量,该Map存储的key为ThreadLocal对象自身,value为我们要存储的对象,这样一来,在不同线程中,持有的其实都是当前线程的变量副本,与其他线程完全隔离,以此来保证线程执行过程中不受其他线程的影响。

下面我们通过代码看下它如何保证线程安全:

ThreadLocal结构:


主要是四个方法:
1. void set(Object value)
设置当前线程的线程局部变量的值。
2. public Object get()
该方法返回当前线程所对应的线程局部变量。
3. public void remove()
将当前线程局部变量的值删除,目的是为了减少内存的占用,该方法是JDK 5.0新增的方法。需要指出的是,当线程结束后,对应该线程的局部变量将自动被垃圾回收,所以显式调用该方法清除线程的局部变量并不是必须的操作,但它可以加快内存回收的速度。
4. protected Object initialValue()
返回该线程局部变量的初始值,该方法是一个protected的方法,显然是为了让子类覆盖而设计的。这个方法是一个延迟调用方法,在线程第1次调用get()或set(Object)时才执行,并且仅执行1次。ThreadLocal中的缺省实现直接返回一个null。

值得一提的是,在JDK5.0中,ThreadLocal已经支持泛型,该类的类名已经变为ThreadLocal。API方法也相应进行了调整,新版本的API方法分别是void set(T value)、T get()以及T initialValue()。

我们看下set方法的实现:

    public void set(T value) {Thread t = Thread.currentThread();ThreadLocalMap map = getMap(t);if (map != null)map.set(this, value);elsecreateMap(t, value);}

可以看到,先通过Thread.currentThread()方法获取到了当前线程,然后如果取不到map对象,就会创建,下面看下create方法

    void createMap(Thread t, T firstValue) {t.threadLocals = new ThreadLocalMap(this, firstValue);}

很简单的方法,就是新建一个ThreadLocal的Map,这个map以ThreadLocal自身为key,以我们要设值的对象为value,创建出来map之后,将对象赋值到线程的局部变量去。
看到这里,就知道ThreadLocal主要目的就是将变量设值到当前的线程上,以此来保证线程安全。
那么下面看下get方法:

    public T get() {Thread t = Thread.currentThread();ThreadLocalMap map = getMap(t);if (map != null) {ThreadLocalMap.Entry e = map.getEntry(this);if (e != null) {@SuppressWarnings("unchecked")T result = (T)e.value;return result;}}return setInitialValue();}

可以看出来,get方法就是拿的当前线程的局部变量threadLocals,然后从中取出map中存储的对象,这样每个线程中获取的一定是自己线程中存储的对象了。
由上述分析可知,使用ThreadLocal是可以保证线程安全的。
ThreadLocal实际上是为解决多线程程序的并发问题提供了一种新的思路(区别与sychronized关键字)。
ThreadLocal这个类提供线程本地的变量。这些变量与一般正常的变量不同,它们在每个线程中都是独立的。ThreadLocal实例最典型的运用就是在类的私有静态变量中定义,并与线程关联。
我们看下具体的使用场景吧:

  • 我们知道SimpleDateFormat是非线程安全的,并发场景下会出现格式化时间错误的问题,那么在这里我们就可以使用ThreadLocal来解决此类问题。
    private static ThreadLocal<SimpleDateFormat> sdt = new ThreadLocal<SimpleDateFormat>();public static final SimpleDateFormat getSdt() {if (null == sdt.get()) {sdt.set(new SimpleDateFormat("MM月dd日HH:mm"));}return sdt.get();}
  • 看另外一个场景,一个请求过来,会带有一堆的c参数(可以理解为客户端的一些标志),我们的应用处理过程中,大部分地方又不需要关心该参数,可能在某个请求他人接口的时候需要了,如果我们把所有代码都带上这个c参数,那么未免代码看着太过丑陋,这种情况下,我们可以构建一个filter,在请求过来的时候,在filter中将c参数放置到ThreadLocal中,在整个调用链中如果需要使用,直接从ThreadLocal中获取即可。
  • 另外一个例子是动态数据源的使用,我们可以使用ThreadLocal来保证当次线程调用中只使用一种数据源。这部分内容下个文章我会单独列出来讲解一下。

最后我们在提一点,就是使用ThreadLocal是否会造成内存泄漏,这一点答出来相信应该会给自己很多加分吧~
这个是ThreadLocal自身的注释:

每一个线程对资源副本都有一个weekRefrence:只要线程还在运行,使用ThreadLocal就是可以获取的。当一个线程运行结束销毁时,所有的资源副本都是可以被垃圾回收的(ThreadLocalMap对象保存在Thread对象中,当某个线程终止后,存储在其中的线程隔离的变量,也将作为Thread实例的垃圾被回收掉,所以完全不用担心内存泄漏的问题),这段注释表明,ThreadLocal的使用是不会造成内训泄露的。

ThreadLocal面试题相关推荐

  1. 商城项目技术(不含秒杀)

    谷粒商城项目总结 文章目录 谷粒商城项目总结 一.商品上架 1.为什么上架的商品信息不存到数据库? 2.上架细节 2.商品检索过程 3.检索商品的更新与删除 二.说一下项目中登录功能是怎么实现的? 分 ...

  2. 第 5-4 课:ThreadLocal 详解 + 面试题

    什么是 ThreadLocal? ThreadLocal 诞生于 JDK 1.2,用于解决多线程间的数据隔离问题.也就是说 ThreadLocal 会为每一个线程创建一个单独的变量副本. Thread ...

  3. Java 200+ 面试题补充 ThreadLocal 模块

    让我们每天都有进步,老王带你打造最全的 Java 面试清单,认真把一件事做到极致. 本文是前文<Java 最常见的 200+ 面试题>的第一个补充模块. 1.ThreadLocal 是什么 ...

  4. 面试题:彻底理解ThreadLocal 索引的利弊 背1

    .索引利弊   --整理 1.索引的好处 a.提高数据检索的效率,降低检索过程中必须要读取得数据量,降低数据库IO成本. b.降低数据库的排序成本.因为索引就是对字段数据进行排序后存储的,如果待排序的 ...

  5. (Java多线程常见面试题)ThreadLocal 是什么?有哪些使⽤场景?

    最近在研究多线程项目时,无意间看到一个很有意思的Java类----ThreadLocal.于是乎一向对于新东西充满好奇的我又开始了一系列深挖细究,在经过学习和参考网上其他大佬的见解后,现将自己的理解作 ...

  6. java面试题(24)ThreadLocal的原理和使用场景

    一篇讲的很好的链接 1.四种引用类型   引用类型分为:强引用.软引用.弱引用.虚引用.   强引用:一般我们使用的都是强引用,特点是不会被gc回收,宁愿抛出内存溢出异常也不会回收:   软引用:特点 ...

  7. FastThreadLocal吞吐量居然是ThreadLocal的3倍

    目前关于FastThreadLocal的很多文章都有点老有点过时了(本文将澄清几个误区),很多文章关于FastThreadLocal介绍的也不全,希望本篇文章可以带你彻底理解FastThreadLoc ...

  8. java 实体类包含list 怎么取值_2019 最新 500 道 Java 面试题

    2015 年,因为工作岗位的变动,开始负责给集团招聘一些技术人员,出于对公司的负责,也为了更好的胜任技术经理的职位,在面试的这件事上,我做了大量的"功课",首先我研究了几乎所有大厂 ...

  9. java面试题2019 答案

    Java 面试随着时间的改变而改变.在过去的日子里,当你知道 String 和 StringBuilder 的区别(String 类型和 StringBuffer 类型的主要性能区别其实在于 Stri ...

最新文章

  1. Acalvio正式推出其新型安全防御技术——流欺骗
  2. 第一章——数据结构之绪论
  3. 连续 3 天,企业容器应用实战营上海站来啦!
  4. Golang package
  5. [css] 固定的外框尺寸,里面的图片尺寸不固定,如何让图像自适应外框呢?
  6. springboot入门_模板
  7. PyQt5笔记(03) -- 消息框
  8. Linux逻辑运算优先级,linux中的逻辑运算和正则表达式
  9. 利用jmeter做一个简单的性能测试并进行参数化设置
  10. 支付安全不能说的那些事
  11. 安卓12解除进程限制的第三种方式:黑阈
  12. PBS Torque 5.1.3安装配置
  13. 12.7亿入股五星电器背后,京东家电想成为线上线下“王者”
  14. 【Python】具有异常处理功能的计算BMI值的python程序
  15. log4j 配置详解(超详细)
  16. springboot 实现图片上传功能
  17. 2.支付10s倒计时
  18. 基于html的购物网站【华为手机购物网站制作】学生网页设计作业源码
  19. 7款可以实现 PDF 转换 Word 格式的免费在线工具
  20. 使用少量数据去除神经网络中的水印 -- WILD

热门文章

  1. NYOJ203-三国志
  2. iOS_苹果内购详细步骤
  3. Python 之月份加一
  4. html5 游戏 算法,台球类html5游戏的AI设计与核心算法的实现
  5. 龙果最新微服务架构的分布式事务解决方案视频课程(31课全)
  6. Netapp存储FTP功能配置
  7. 【深度学习】跟李沐学ai 线性回归 从零开始的代码实现超详解
  8. cad服务器为空该如何设置,Excel服务器2013/2015/2016/2017/CAD服务器教程-角色和用户-设置系统管理员密码双加密|Excel服务器教程...
  9. 各种sharebutton 的使用
  10. 入门数据结构,看这一篇就够了!