-
前言
-
1.代码应用:
-
2.简单介绍Threadlocal的内部结构:
-
3.Threadlocal的内存泄露问题解决:
-
总结
前言
ThreadLocal从字面意思就可以解释它的意思,本地线程变量,要理解ThreadLocal的意思,我们需要了解JMM(java内存模型),java内存模型中规定内存分为主内存和工作内存(本地内存)。线程访问主内存的变量都是共享的,假如想要私有的话,就用到了ThreadLocal,ThreadLocal实现了线程之间的数据隔离。
1.代码应用:
简单实现的ThreadLocal的代码应用:
ThreadLocal<String>threadLocal=new ThreadLocal<>();
@Test
public void testThreadAll(){
for (int i=0;i<10;i++){
testThreadLocal();
}
}
public void testThreadLocal(){
Thread thread1=new Thread(new Runnable() {
@Override
public void run() {
threadLocal.set("111");
printResult("th1");
System.out.println(threadLocal.get());
}
});
Thread thread2=new Thread(new Runnable() {
@Override
public void run() {
threadLocal.set("222");
printResult("th2");
System.out.println(threadLocal.get());
}
});
thread1.start();
thread2.start();
}
void printResult(String name){
System.out.println(name+":"+threadLocal.get());
}
输出的结果为:
th1:111
th2:222
111
th1:111
111
222
th2:222
222
th1:111
111
th2:222
th2:222
222
222
th1:111
111
th1:111
111
th2:222
222
th2:222
222
th1:111
111
th1:111
111
th2:222
222
th1:111
111
th2:222
222
th1:111
111
th2:222
222
th1:111
111
th2:222
222
证明线程之间的变量确实被隔离了。
2.简单介绍Threadlocal的内部结构:
Threadlocal提供了get、set、remove方法供使用操作,内部通过内部类ThreadLocalMap 进行管理这线程变量的对应关系,里面的Entry是继承WeakReference(弱引用),并没有使用链表。不同的thread通过hreadLocalHashCode进行数组存储。这里没有链表,看源码总结出来流程是:
-
key如果在数组的位置相同进行值覆盖返回 -
如果当前位置为空,初始化一个Entry对象放置在对应位置上 -
如果key不相同,位置不为空,找下一个空位置进行存储,如果冲突严重,效率肯定低
3.Threadlocal的内存泄露问题解决:
上面有提到ThreadLocal里面使用的是弱引用,当发生Gc回收的时候,弱引用的key会被回收,加入value没有被移除的话就有可能发生内存泄露,避免内存泄露的方法就是用过之后进行remove。
总结
上面就是我总结的关于ThreadLocal的几个重要的点,代码是帮助大家更好的理解ThreadLocal的场景应用,下面两点面试的时候经常会被问到,当然工作当中也应该尽量设计的时候避免内存泄露问题的存在。还有就是synchronized是通过线程等待实现的线程安全,TheadLocal相当于是牺牲了内存空间来保证的线程安全。如果你想跟我有更多的交流,关注我的公众号:Java时间屋 感谢你的阅读。
原文始发于微信公众号(Java时间屋):56-谈谈ThreadLocal
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/251826.html