JAVA基础系列:ThreadLocal

1. 思路

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

  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和线程池

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

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

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )

Java ThreadLocal的内存泄漏问题

ThreadLocal提供了线程独有的局部变量,可以在整个线程存活的过程中随时取用,极大地方便了一些逻辑的实现。常见的ThreadLocal用法有:\存储单个线程上下文信息。比如存储id等;\使变量线程安全。变量既然成为了每个线程内部的局部变量,自然就不会存在并发问题了;\减少参数传递。比如做一个trace工具,能够输出工程从开始到结