ThreadLocal 简单解析
ThreadLocal 简单解析
基于jdk1.8
ThreadLocal一定不陌生,开发中常用,也是面试里的常客了,但是往往我们可能只是知道该类的作用。学习该类对于个人的多线程编码能力是大有裨益的,同时也可以知道使用中需要注意的地方
ThreadLocal也叫本地线程变量,我们知道ThreadLocal为每个线程创建一个副本,线程隔离的。
主要有4个公共方法get、remove、set、withInitial
看看set和remove 有set,get、remove就没必要细看了一看就明白了。
1.set
public void set(T value) {
Thread t = Thread.currentThread();//获取当前线程、也是能隔离的本质
ThreadLocalMap map = getMap(t);//getMap比较简单 return t.threadLocals; 后面再看这个t.threadLocals
if (map != null)
map.set(this, value); //好说不就是类似map的put值么,但是注意key是this写死了,表明一个ThreadLocal对象只能存一个值
else
createMap(t, value); //空 new ThreadLocalMap(this, firstValue)
}
t.threadLocals明显是线程类Thread中的变量
ThreadLocal.ThreadLocalMap threadLocals = null;
static class ThreadLocalMap {
static class Entry extends WeakReference<ThreadLocal<?>> {
/** The value associated with this ThreadLocal. */
Object value;
Entry(ThreadLocal<?> k, Object v) {
super(k);
value = v;
}
}
private static final int INITIAL_CAPACITY = 16;
private Entry[] table;
private int threshold;
//通过createMap初始化来看
ThreadLocalMap(ThreadLocal<?> firstKey, Object firstValue) {
table = new Entry[INITIAL_CAPACITY];//16的Entry数组
int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY - 1);//数组位置
table[i] = new Entry(firstKey, firstValue);//放值
size = 1;
setThreshold(INITIAL_CAPACITY);//阀值16*2/3 容量的2/3大小
}
}
ThreadLocalMap明显就是一个简化版的hashmap,数据结构是Entry数组,每次2倍扩容,没有链表红黑树,其实现了自己的寻址,我想看懂这些应该是不难的。
这里也能看出Thread、ThreadLocal、ThreadLocalMap的关系
Thread存在一个ThreadLocalMap,ThreadLocalMap是一个类型Map的结构可以存储多个ThreadLocal
ThreadLocalMap与WeakReference也理解下,ThreadLocalMap内部存储单元Entry继承WeakReference,是弱引用
弱引用:如果一个对象只具有弱引用,那么垃圾回收器在扫描到该对象时,无论内存充足与否,都会回收该对象的内存。
这么做主要是为了内存回收考虑,当我们用普通线程没问题,线程用完自己会关闭释放内存,但是线程池呢,线程一直存活,是不是意味着这个Map一直存在,但是换任务了等等,其中很多的存储都会是废值,
程序执行时间长了,就可能引发OOM内存泄漏问题,特别是我们的value再比较大。因此用了弱引用,内存不够GC时会干掉key,但是value却还是存在的,而ThreadLocalMap的set、get、remove方法操作元素时会检查null
的key然后释放value,就解决这个问题。但也不绝对,如果ThreadLocal实例我们置null,那ThreadLocal就会回收,但是Map就会一直存在,也可能引发OOM。
map.set
private void set(ThreadLocal<?> key, Object value) { // We don't use a fast path as with get() because it is at
// least as common to use set() to create new entries as
// it is to replace existing ones, in which case, a fast
// path would fail more often than not. Entry[] tab = table;
int len = tab.length;
int i = key.threadLocalHashCode & (len-1); for (Entry e = tab[i];
e != null;
e = tab[i = nextIndex(i, len)]) {
ThreadLocal<?> k = e.get(); if (k == key) {
e.value = value;
return;
} if (k == null) {
replaceStaleEntry(key, value, i);//这里是替换null key的
return;
}
} tab[i] = new Entry(key, value);
int sz = ++size;
if (!cleanSomeSlots(i, sz) && sz >= threshold)//这里就是清理null key的
rehash();
}
其它没什么多的看的了
总结:需要明白Thread、ThreadLocal、ThreadLocalMap的关系。
ThreadLocalMap是线程的成员变量,不同的线程有不同的ThreadLocalMap,ThreadLocalMap中存储不同的ThreadLocal,实际简单说就是一个线程可以创建多个本地线程变量存多个值且只属于本线程。
WeakReference弱引用往往是面试中问到ThreadLocal类常会深入到的一个点,要知道怎么回事。正常场景ThreadLocal如果我们只是简单的创建,不自己置null,或者创建了ThreadLocal又不用等待操作也不会OOM,正常操作完全没什么大问题。
ThreadLocal 简单解析的更多相关文章
- 对 cloudwu 简单的 cstring 进行简单解析
题外话 以前也用C写过字符串,主要应用的领域是,大字符串,文件读取方面.写的很粗暴,用的凑合着.那时候看见云风前辈的一个开源的 cstring 串. 当时简单观摩了一下,觉得挺好的.也没细看.过了较长 ...
- 基于DOM的XSS注入漏洞简单解析
基于DOM的XSS注入漏洞简单解析http://automationqa.com/forum.php?mod=viewthread&tid=2956&fromuid=21
- 15.5 自学Zabbix之路15.5 Zabbix数据库表结构简单解析-其他 表
点击返回:自学Zabbix之路 自学Zabbix之路15.5 Zabbix数据库表结构简单解析-其他 表 1. Actions表 actions表记录了当触发器触发时,需要采用的动作. 2.Aler ...
- 深度优先搜索DFS和广度优先搜索BFS简单解析(新手向)
深度优先搜索DFS和广度优先搜索BFS简单解析 与树的遍历类似,图的遍历要求从某一点出发,每个点仅被访问一次,这个过程就是图的遍历.图的遍历常用的有深度优先搜索和广度优先搜索,这两者对于有向图和无向图 ...
- List<T>集合的Sort自定义排序用法简单解析
List<T>集合的Sort自定义排序用法简单解析: 如下:一系列无序数字,如果想要他们倒序排列,则使用如下代码: 那么如何理解这段代码呢? (x,y)表示相邻的两个对象,如果满足条件:x ...
- Maven项目pom.xml文件简单解析
Maven项目pom.xml简单解析 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="h ...
- 自学Zabbix之路15.1 Zabbix数据库表结构简单解析-Hosts表、Hosts_groups表、Interface表
点击返回:自学Zabbix之路 点击返回:自学Zabbix4.0之路 点击返回:自学zabbix集锦 自学Zabbix之路15.1 Zabbix数据库表结构简单解析-Hosts表.Hosts_grou ...
- 自学Zabbix之路15.2 Zabbix数据库表结构简单解析-Items表
点击返回:自学Zabbix之路 点击返回:自学Zabbix4.0之路 点击返回:自学zabbix集锦 自学Zabbix之路15.2 Zabbix数据库表结构简单解析-Items表 Items表记录了i ...
- 自学Zabbix之路15.3 Zabbix数据库表结构简单解析-Triggers表、Applications表、 Mapplings表
点击返回:自学Zabbix之路 点击返回:自学Zabbix4.0之路 点击返回:自学zabbix集锦 自学Zabbix之路15.3 Zabbix数据库表结构简单解析-Triggers表.Applica ...
随机推荐
- 英语阅读——The confusing pursuit of beauty
这篇文章是<新视野大学英语>第四册的第二单元的文章,很好的一篇议论文,读起来也很有意思. 1 If you're a man, at some point a woman will ask ...
- 前端之jquery1
jquery介绍 jQuery是目前使用最广泛的javascript函数库.据统计,全世界排名前100万的网站,有46%使用jQuery,远远超过其他库.微软公司甚至把jQuery作为他们的官方库. ...
- c# Winform 继承窗体 无法拖动修改控件大小
问题描述: 一个窗体集成父窗体,发现无法直接拖动修改的控件,比如修改大小等 特征: 不禁使父窗体控件,就算新加一个控件也会这样:鼠标放到控件移动手方块上会出现一个“继承的控件”的tooptip, 异常 ...
- 史上最详细JVM,Java内存区域讲解
本人免费整理了Java高级资料,一共30G,需要自己领取:传送门:https://mp.weixin.qq.com/s/JzddfH-7yNudmkjT0IRL8Q 运行时数据区域 JVM载执行Jav ...
- Java自定义注解(1)
Java注解简介 1. Java注解(Annotation) Java注解是附加在代码中的一些元信息,用于一些工具在编译. 运行时进行解析和使用,起到说明.配置的功能. 注解相关类都包含在java.l ...
- 盘点10个CAD难点,看看有没有让你崩溃的,解决方法一并奉上
蜀道难,难于上青天”,对于很多学习CAD的小伙伴来说CAD就跟蜀道一样,太难了,下面小编分享几个在学习CAD过程中会遇到的问题以及解决的方法,一起来看看吧! 1. 如何替换找不到的原文字体? 答:复制 ...
- Microsoft Office自制安装指南 —Nusen_Liu
Microsoft Word 2010 正版下载安装步骤 版权来自:Nusen_Liu 1. 解压文件(推荐解压到当前文件夹,大神也可以自定义的)下载地址在第16步 (*^__^*) 2. 解 ...
- ucoreOS_lab4 实验报告
所有的实验报告将会在 Github 同步更新,更多内容请移步至Github:https://github.com/AngelKitty/review_the_national_post-graduat ...
- 使用weui开发微信小程序
一.使用weui 学习一个新的技术,想要最短时间掌握并熟练使用它,那就是直接做项目了.把技术直接应用到项目中来,直接做出东西,这是我的方法,因为我很懒不太喜欢看一步一步看文档,看理论. 那怎么使用we ...
- [20190524]sqlplus 与输出&.txt
[20190524]sqlplus 与输出&.txt --//在sqlplus下 &一般作为参数替换,如何要输出&,一般有几种情况.据说这个问题是asktom站点查看最多的问题 ...