解析ThreadLocal

作者: Real_man | 来源:发表于2019-05-13 10:25 被阅读11次

ThreadLocal是在开发中相对比较常见的工具类了,可以在多线程环境下保证线程安全,其基本原理就是给每一个对象都分配一个属于当前线程的私有对象,这样线程之间拿到的对象就不会相互冲突了。

可以想象成,如果多个人公用一个厕所的时候,因为厕所的一些限制,有很多的人都不能冒然的使用厕所,如果每一个人来的时候都给他一个单独的厕所这样相互之间就不会打扰了,缺点的话也很明显可以看出来就是浪费资源。所以在用完的时候要记得销毁资源。

有的人可能会问你再什么时候下使用ThreadLocal呢?

  • 在Spring的事务中,默认内部用的是ThreadLocal给每一个线程分配一个单独的连接,不过这是内部已经封装好的了,不算是我们自己写的
  • 在Web应用中,有的时候要对一些请求做单独的处理,响应做额外的处理,每个人的写法都不一样,我有见过一些人在每一个请求的时候对应一个线程,并且对每个请求都有一些ThreadLocal相关的变量,存储请求的信息,以便在后续的处理中再从ThreadLocal中去拿
  • 比较常见的例子,应该是SimpleDateFormat了,这个对象在多线程下会出现一定的问题,一般在高并发的场景下,都会使用ThreadLocal给每个线程分配一个SimpleDateFormat对象。

知道了原理在使用的时候考虑下,或者在对应的场景下想想能不能用ThreadLocal去做。

内部结构

只是知道了其基本使用的话,相对还是不够,其内部的数据结构也很有意思,在看过之后才发现其中的巧妙。

  • 每个Thread对象内部都有一个ThreadLocal.ThreadLocalMap属性,属性名为threadLocals,在创建线程之后可以直接通过t.threadLocals访问
image-20190513101303375

当调用ThreadLocal的set方法时:

  • 获取当前Thread的ThreadLocalMap属性,如果当前线程的ThreadLocalMap为空的话,会进行初始化并赋值,如果不为空,则直接赋值

当有多个ThreadLocal对象时候,其实每个线程内部的ThreadLocalMap属性里面的Entry数组,对应的下标为ThreadLocal的hashCode进行取余,然后再构建Entry对象。

其实就是一个线程内部可以存储多个ThreadLocal给的线程私有对象,只不过ThreadLocal对象是访问那些线程私有对象的入口。

内存泄漏问题

关于ThreadLocal如果不进行Remove是否会导致内存泄漏?

通过上面我们知道Thread中的ThreadLocalMap属性中的Entry表都是弱引用的对象,其引用为ThreadLocal对象,那么弱引用对象一般在进行垃圾回收的时候都会被回收掉。

ThreadLocal在没有外部强引用时,发生GC时会被回收,如果创建ThreadLocal的线程一直持续运行,那么这个Entry对象中的value就有可能一直得不到回收,发生内存泄露。

记得在使用ThreadLocal完毕之后,调用ThreadLocal.remove方法。

最后

ThreadLocal也算是一个比较经典的知识点了,通过它可以问出

  • 引用类型
  • Map的数据结构
  • 线程安全
  • 实际场景中的用法

希望对你有帮助

参考

相关文章

  • 线程中的ThreadLocal

    ThreadLocal解析

  • JDK ThreadLocal解析

    Java ThreadLocal解析 ThreadLocal 线程本地变量, 线程私有, 在 Thread 类中用...

  • ThreadLocal 深度解析

    一.对ThreadLocal的理解二.深入解析ThreadLocal类三.ThreadLocal的应用场景 对Th...

  • ThreadLocal解析

    前言 刚看过EventBus和AndroidEventBus的源码, 发现里面都有用到ThreadLocal, 那...

  • ThreadLocal解析

    前言 在各大公司招聘笔试和面试题题中,都遇到了很多ThreadLocal的问题,最近博主在面试的时候也被两次问到过...

  • ThreadLocal解析

    一、简介 首先我们需要知道Thread.currentThread()获取当前线程对象,同一个线程每次获取的都是同...

  • ThreadLocal解析

    前言 我们都知道ThreadLocal用于为每个线程存储自己的变量值,起到线程间隔离的作用,那么它到底是怎么运行的...

  • ThreadLocal解析

    ThreadLocal,顾名思义,肯定是与Thread类有关系的,所以先从Thread类入手。 Thread和Th...

  • ThreadLocal解析

    原理 产生线程安全问题的根源在于多线程之间的数据共享。如果没有数据共享,就没有多线程并发安全问题。ThreadLo...

  • ThreadLocal解析

    我们都知道,ThreadLocal在多线程中使用,即多线程共享一个变量,正常情况下线程安全。其主要原理是内部持有的...

网友评论

    本文标题:解析ThreadLocal

    本文链接:https://www.haomeiwen.com/subject/tqtlaqtx.html