ThreadLocal(底层原理/内存泄漏/应用)
2021-03-02 13:53:11 0 举报
AI智能生成
ThreadLocal(底层原理/内存泄漏/应用)
作者其他创作
大纲/内容
阅读导航
<b style=""><font color="#0076b3">线程 👉</font></b>
<b><font color="#0076b3">CPU+JMM</font></b> 👉
<b><font color="#0076b3">CAS+Volatile</font></b> 👉
<b><font color="#0076b3">Synchronized</font></b> 👉
<b><font color="#0076b3">JUC</font></b> 👉
<b><font color="#0076b3">线程池</font></b> 👉
<b style="font-size: inherit;"><font color="#f15a23">ThreadLocal</font></b><br>
为每个线程创建一个变量的副本,每个线程可以单独访问自己的副本,而不与其他线程共享,当前线程结束后GC
使用
声明ThreadLocal对象:ThreadLocal<Person> tl = new ThreadLocal<>();
调用方式
tl.set(new Person());
tl.get()
实现原理
每个线程(Thread类)都有一个<b>ThreadLocalMap</b>对象(<b>threadLocals</b>),<b><font color="#662c90">key为threadLocal对象(tl)的弱引用,value为对应的副本值</font></b>
<b>ThreadLocalMap数据结构</b>:类似 HashMap 的 key-value 键值对,底层实现是table[]数组,没有链表结构,使用开放定址法解决hash冲突
源码分析
set()
先获取当前线程:Thread t = Thread.currentThread();
再获取属于当前线程的map对象
ThreadLocalMap <font color="#16884a">map</font> = <font color="#662c90">getMap()</font>;<br><font color="#662c90">return t.threadlocals</font>;(线程类的属性)
通过 map.set(this, value)
底层 new Entry(key, value) 给数组赋值,Entry类继承自WeakReference<br>Entry类的构造方法中有 super(key):<b>创建弱引用对象指向key(tl 对象)</b>
弱引用防止<br>内存泄漏
ThreadLocal<Person> tl = new ThreadLocal<>(); tl 指向ThreadLocal对象,<b>强引用</b>
tl.set(new Person()); => map.set(<b> key</b>, Person); key是指向ThreadLocal对象的 <b>弱引用</b>
这样当外部强引用消失时(tl=null或者方法运行完弹栈),ThreadLocal对象能够得到回收<br>否则如果map的key也是强引用,则只要线程还在运行,ThreadLocal的内存就不会被释放
get()
拿到当前线程,获取map对象,通过Entry中的key获取value后返回
remove()
拿到当前线程,获取map对象,将 map 中对应 tl 的 key 移除
什么地方存在内存泄露?<br>
①外部强引用消失时,ThreadLocal对象可能无法回收,导致内存泄漏(jdk优化:<b>通过弱引用已解决</b>)
②ThreadLocal对象被回收后,map中Entry的value就访问不到了,如果线程一直运行则导致内存泄漏
解决②:ThreadLocal用完后,<b>一定要调用remove()方法(<font color="#662c90">线程池慎用ThreadLocal</font>)</b>
应用
线程本地变量/存储,避免了将对象作为参数传递的麻烦
延伸:把变量设置为static不是也可以传递吗?
static有局限性,多线程访问时会有数据污染
threadlocal可以保证每个线程访问私有的变量
Spring中@Transactional注解,使用ThreadLocal存储数据库连接connection,保证事务方法每次拿到的都是同一个connection
Spring中Bean在singleton作用域时,使用ThreadLocal解决共享变量的线程安全问题
关于作者
<b style=""><font color="#b296c7">我的博客</font></b> 👉
<b><font color="#00a650">微信公众号</font></b> 👉
<b><font color="#f15a23">GitHub 导航</font></b> 👉
<b><font color="#662c90">ProcessOn 主页 👉</font></b>
0 条评论
下一页