JAVA基础系列:ThreadLocal
1. 思路
什么是ThreadLocal?
ThreadLocal类顾名思义可以理解为线程本地变量。也就是说如果定义了一个ThreadLocal,每个线程往这个ThreadLocal中读写是线程隔离,互相之间不会影响的。它提供了一种将可变数据通过每个线程有自己的独立副本从而实现线程封闭的机制。它大致的实现思路是怎样的?
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() 方法清理。
参考网址
- ThreadLocal-面试必问深度解析
- Java 源码解析实战 - ThreadLocal 原理
- 【Java并发学习五】图解ThreadLocal
- 彻底理解ThreadLocal
- ThreadLocal源码解读
- 死磕Java之聊聊ThreadLocal源码(基于JDK1.8)
- Java面试必问,ThreadLocal终极篇
- 2019/03面试题-并发为主
- 深入理解 ThreadLocal (这些细节不应忽略)
- https://www.iteye.com/topic/1123824
JAVA基础系列:ThreadLocal的更多相关文章
- 2015年12月28日 Java基础系列(六)流
2015年12月28日 Java基础系列(六)流2015年12月28日 Java基础系列(六)流2015年12月28日 Java基础系列(六)流
- Java基础系列--static关键字
原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/8477914.html 一.概述 static关键字是Java诸多关键字中较常使用的一个,从 ...
- Java基础系列-ArrayList
原创文章,转载请标注出处:<Java基础系列-ArrayList> 一.概述 ArrayList底层使用的是数组.是List的可变数组实现,这里的可变是针对List而言,而不是底层数组. ...
- Java基础系列-Collector和Collectors
原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/10748925.html 一.概述 Collector是专门用来作为Stream的coll ...
- Java基础系列-二进制操作
原创文章,转载请标注出处:<Java基础系列-二进制操作> 概述 Java源码中涉及到大量的二进制操作,非常的复杂,但非常的快速. Java二进制表示法 首先了解下二进制,二进制是相对十进 ...
- Java基础系列-equals方法和hashCode方法
原创文章,转载请标注出处:<Java基础系列-equals方法和hashCode方法> 概述 equals方法和hashCode方法都是有Object类定义的. publi ...
- Java基础系列-Comparable和Comparator
原创文章,转载请标注出处:<Java基础系列-Comparable和Comparator> 一.概述 Java中的排序是由Comparable和Comparator这两个接 ...
- Java基础系列--HashMap(JDK1.8)
原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/10022092.html Java基础系列-HashMap 1.8 概述 HashMap是 ...
- 夯实Java基础系列1:Java面向对象三大特性(基础篇)
本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 [https://github.com/h2pl/Java-Tutorial](https: ...
- 夯实Java基础系列3:一文搞懂String常见面试题,从基础到实战,更有原理分析和源码解析!
目录 目录 string基础 Java String 类 创建字符串 StringDemo.java 文件代码: String基本用法 创建String对象的常用方法 String中常用的方法,用法如 ...
随机推荐
- Python程序中的进程操作-进程间通信(multiprocess.Queue)
目录 一.进程间通信 二.队列 2.1 概念介绍--multiprocess.Queue 2.1.1 方法介绍 2.1.2 其他方法(了解) 三.代码实例--multiprocess.Queue 3. ...
- Linux 命名管道
前文中笔者介绍了管道,本文接着介绍命名管道.文中演示所用环境为 Ubuntu 18.04 desktop. 命名管道(named pipe)又被称为先进先出队列(FIFO),是一种特殊的管道,存在于文 ...
- python写文件时,使用代码强制刷新文件
一.实验环境 1.Windows10x64 2.anaconda4.6.9 + python3.7.1(anaconda集成,不需单独安装) 3.pyinstaller3.5 二.任务需求 三.问题描 ...
- VMware下扩展Ubuntu根分区大小
一.查看磁盘信息 使用df命令用来查看文件系统的磁盘空间占用情况,由下可知我的/dev/sda1分区是挂载在根目录下的,本文目标就是来扩容/dev/sda1分区. 二.下载Gparted工具 Gpar ...
- Google工作法
本文转自:https://www.yuque.com/heqingbao/msfy2c/zg56gm 这几天去上海参加Google开发者大会,利用空闲时间读了一本快餐书,书名叫<Google工作 ...
- CodeForces 200D Programming Language
Recently, Valery have come across an entirely new programming language. Most of all the language att ...
- MECE分析法
概述 MECE分析法,是麦肯锡的第一个女咨询顾问 Barbara Minto 在金字塔原理中提出的一个很重要的原则. MECE分析法,全称Mutually Exclusive Collective ...
- Python爬虫:设置Cookie解决网站拦截并爬取蚂蚁短租
前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: Eastmount PS:如有需要Python学习资料的小伙伴可以加 ...
- AppBoxFuture(八): 另类的ORM实现
通常的ORM实现基于配置或注释,由反射或Emit生成相应的Sql语句,然后将Sql发送给数据库解析Sql字符串生成AST再交给优化器处理后执行,返回的数据再经由反射或Emit转换为相应的实体实例. ...
- jQuery-File-Upload $(...).fileupload is not a function $.widget is not a function
使用 jQuery-File-Upload 库的时候碰到了 $(...).fileupload is not a function 和 $.widget is not a function 问题. ...