ThreadLocal
1,ThreadLocal是什么:
ThreadLocal也是解决多线程访问共享变量问题的,不同于加锁,他会在每一个线程内部创建副本,
每个线程独立访问自己内部的副本,不会产生冲突。
2,用法:
public class ThreadLocalTest { static ThreadLocal<String> localVar = new ThreadLocal<>(); static void print(String str) { //打印当前线程中本地内存中本地变量的值 System.out.println(str + " :" + localVar.get()); //清除本地内存中的本地变量 localVar.remove(); } public static void main(String[] args) { Thread t1 = new Thread(new Runnable() { @Override public void run() { //设置线程1中本地变量的值 localVar.set("localVar1"); //调用打印方法 print("thread1"); //打印本地变量 System.out.println("after remove : " + localVar.get()); } }); Thread t2 = new Thread(new Runnable() { @Override public void run() { //设置线程1中本地变量的值 localVar.set("localVar2"); //调用打印方法 print("thread2"); //打印本地变量 System.out.println("after remove : " + localVar.get()); } }); t1.start(); t2.start(); } }
3,原理:
ThreadLocal类:
①内部类:ThreadLocalMap
是一个哈希表,循环数组+开发地址法中线性探测法解决哈希冲突。
什么意思呢?试试想一下:线性探测法会在数组中形成以null隔开的若干‘块’,我们把它类比成拉链法里面的每一个链表。
线性探测法在一个快中(快可能未null)添加元素就相当于尾插法,删除元素,就要调整该快中,被删除元素之后的元素,要前移
保证他们下次能被探测到。就绪拉链法里面的调整指针关系。
Entry数组储存的是key-value键值对,key是ThreadLocal,value是Object对象。
- 参数:
- 方法:主要是哈希表的,增删改查
①增删改查之前,首先要介绍一下expungeStaleEntry()函数,顾名思义删除元素用的
②getEntry():
getEntryAfterMiss():
③set()函数:
replaceStaleEntry()
cleanSomeSlots();
④remove()
⑤rehash()
expungeStaleEntries()
resize()扩容:
总结:ThreadLocalMap(),哈希表,数组+线性探测法解决哈希冲突。初始容量16,扩容*2.
在增删改查中不停清理,失效的TreadLocal元素。
内存泄漏问题:
<1>ThreadLocalMap的Entry数组是key为ThreadLocal的弱引用,而valve是强引用。如果ThreadLocal对象没有被外部强引用,垃圾回收时,key被回收
为null但是value还在。造成内存泄漏。
<2>虽然ThreadLocalMap在get(),set()函数里多次清理key为null的失效元素,但是当没有调用get(),set()时,不会清理。
解决方法:<1>使用完ThreadLocal后手动调用remove方法。
<2>将ThreadLocal定义为private static 随线程一起消亡。
②看完ThreadLocalMap,在回到ThreadLocal类,
- set()
- get()
map空就初始化map
- 虽然ThreadLocalMap是ThreadLocal内部类,但ThreadLocal里并没有ThreadLocalMap参数,
而是通过getMap()方法;获得线程的threadlocalS。
调用getMap的地方也是传入当前线程的
进入Thread类:
ThreadLocalMap实例化在Thread类里作为参数。即每一个线程有一个,哈西表,threadlocals,顾名思义用来存放该
线程ThreadLocals变量的。
ThreadLocal是ThreadLocalMap的封装,提供了set(),get();看起来是每个Threadlocal变量单独get(),set()。背后还是通过每个Thred的
ThredLocalMap统一管理所有ThreadLocal变量;
参考:
https://www.cnblogs.com/fsmly/p/11020641.html
https://baijiahao.baidu.com/s?id=1653790035315010634&wfr=spider&for=pc
https://www.jianshu.com/p/80866ca6c424
https://blog.csdn.net/ywlmsm1224811/article/details/91388109