JAVA基础系列:ThreadLocal

1. 思路

    1. 什么是ThreadLocal?
      ThreadLocal类顾名思义能够理解为线程本地变量。也就是说若是定义了一个ThreadLocal,每一个线程往这个ThreadLocal中读写是线程隔离,互相之间不会影响的。它提供了一种将可变数据经过每一个线程有本身的独立副本从而实现线程封闭的机制。html

    2. 它大体的实现思路是怎样的?
      Thread类有一个类型为ThreadLocal.ThreadLocalMap的实例变量threadLocals,也就是说每一个线程有一个本身的ThreadLocalMap。ThreadLocalMap有本身的独立实现,能够简单地将它的key视做ThreadLocal,value为代码中放入的值(实际上key并非ThreadLocal自己,而是它的一个弱引用)。每一个线程在往某个ThreadLocal里塞值的时候,都会往本身的ThreadLocalMap里存,读也是以某个ThreadLocal做为引用,在本身的map里找对应的key,从而实现了线程隔离。面试

2. 图解

2.1 位置

2.2 结构图

  

2.3 源码关系图

2.4 内存关系图

 

  

 

3. ThreadLocal和线程池

核心线程,销毁线程,反作用(脏数据,内存溢出)安全

ThreadLocl 主要用于线程安全地共享某个变量 ThreadLocl 主要会产生脏数据和内存泄露。这两个问题一般是在线程池的线程中使用ThreadLocal 引起的,由于线程池有线程复用和内存常驻两个特色1.脏数据 线程复用会产生脏数据。因为线程池会重用Thread对象,那么与Thread绑定的类静态属性也会被重用。
  若是在实现线程run() 方法中不显示的调用remove() 清理与线程相关的ThreadLocal 信息。
  若是先一个线程不调用set() 设置初始值,那么就get() 到重用信息,包括ThreadLocl 所关联线对象的值。
2.内存泄露 在源码注释中提示使用static 关键字来修改ThreadLocal。
  在此场景下,寄但愿于ThreadLocal对象失去引用后,触发弱引用机制来回收Entry 的Value 就不现实了。
  在上例中,若是不进行remove() 操做,那么这个线程执行完成后,经过ThreadLocal 对象持有的string对象是不会被释放的。 以上两个问题解决的办法很简单,就是每次用完ThreadLocal 时,必须调用remove() 方法清理。

 

参考网址并发

  1. ThreadLocal-面试必问深度解析
  2. Java 源码解析实战 - ThreadLocal 原理
  3. 【Java并发学习五】图解ThreadLocal
  4. 完全理解ThreadLocal
  5. ThreadLocal源码解读
  6. 死磕Java之聊聊ThreadLocal源码(基于JDK1.8)
  7. Java面试必问,ThreadLocal终极篇
  8. 2019/03面试题-并发为主
  9. 深刻理解 ThreadLocal (这些细节不该忽略)
  10. https://www.iteye.com/topic/1123824
相关文章
相关标签/搜索