博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ThreadLocal为什么要用WeakReference
阅读量:4324 次
发布时间:2019-06-06

本文共 3100 字,大约阅读时间需要 10 分钟。

先上一张图看一下ThreadLocal的内部结构,每个Thread对象内部都维护了一个ThreadLocal.ThreadLocalMap

我们在上图看到的就是三个Thread对象内部格子的ThreadLocalMap

这里要说的不是ThreadLocal,是ThreadLocal为什么要用WeakReference

static class ThreadLocalMap {        static class Entry extends WeakReference
> { Entry(ThreadLocal
k, Object v) { super(k); value = v; }

弱引用WeakReference

弱引用只要发生了gc就会被回收,但前提是只有弱引用,没有强引用(这点本身也不容易做到)

WeakReference
weakReference = new WeakReference<>(new Apple("1"));try { Thread.sleep(2000L);} catch (InterruptedException e) { e.printStackTrace();}System.out.println(weakReference.get());//1System.gc();//遇到gc就回收了System.out.println(weakReference.get());//null

引用传递的特殊情况

1、传递的入参是null,方法内new了,也不会影响到外面null的对象,还是null的

2、传递的入参不是null,方法内=null了,也不会影响到外面不是null的对象
3、传递的入参不null,传递到线程中,线程运行中,外面把入参设置为null,线程内继续不是null
总结,别管里面外面 null变!null !null变null 都不会隔层影响原来啥样还啥样

//我们在这里只插入一段模拟线程运行的情况     ……    obj = new ObjectPassing();    obj.setName("name");    MyThread myThread = new MyThread(obj);//obj不是空的传入新线程    new Thread(myThread).start();//线程不停的打印obj的name字段值    Thread.sleep(1000);    obj = null;//将外面的obj置为空后,线程打印的仍然不为空,这点需要先明确    System.out.println("2:"+obj);    Thread.sleep(1000000);}public void testNullPassFunc(ObjectPassing obj){    obj = new ObjectPassing();    obj.setName("zxp");    System.out.println("2:"+obj);}public void testNullPassFunc2(ObjectPassing obj){    obj = null;    System.out.println("2:"+obj);}@Datastatic class ObjectPassing{    private String name;}1:null2:ParameterPassing.ObjectPassing(name=zxp)3:null=======================1:ParameterPassing.ObjectPassing(name=name)2:null3:ParameterPassing.ObjectPassing(name=name)=======================1:name1:name2:null1:name1:name1:name……
public class MyThread implements Runnable {    ParameterPassing.ObjectPassing objectPassing = null;    public MyThread(ParameterPassing.ObjectPassing objectPassing){        this.objectPassing = objectPassing;    }    @Override    public void run() {        while (true){            System.out.println("1:"+objectPassing.getName());            try {                Thread.sleep(500);            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }}

分析ThreadLocal与WeakReference

分析一下为什么ThreadLocal要用WeakReference 不用有什么问题

ThreadLocal local = new ThreadLocal();local.set("当前线程名称:"+Thread.currentThread().getName());//将ThreadLocal作为key放入threadLocals.Entry中Thread t = Thread.currentThread();//注意断点看此时的threadLocals.Entry数组刚设置的referent是指向Local的,referent就是Entry中的key只是被WeakReference包装了一下local = null;//断开强引用,即断开local与referent的关联,但Entry中此时的referent还是指向Local的,为什么会这样,当引用传递设置为null时无法影响传递内的结果System.gc();//执行GCt = Thread.currentThread();//这时Entry中referent是null了,被GC掉了,因为Entry和key的关系是WeakReference,并且在没有其他强引用的情况下就被回收掉了//如果这里不采用WeakReference,即使local=null,那么也不会回收Entry的key,因为Entry和key是强关联//但是这里仅能做到回收key不能回收value,如果这个线程运行时间非常长,即使referent GC了,value持续不清空,就有内存溢出的风险//彻底回收最好调用remove//即:local.remove();//remove相当于把ThreadLocalMap里的这个元素干掉了,并没有把自己干掉System.out.println(local);

 

转载于:https://www.cnblogs.com/zxporz/p/10900852.html

你可能感兴趣的文章
20139216网络攻防技术第七次作业
查看>>
Sublime Text 配置
查看>>
【杂谈】需要mark的一些东西
查看>>
P2731 骑马修栅栏 欧拉函数
查看>>
sort函数
查看>>
CentOS-6.3安装配置Nginx
查看>>
女陔说"你不懂我", 到底什么意思
查看>>
uva11149
查看>>
S/4HANA中的销售计划管理
查看>>
【图灵学院09】RPC底层通讯原理之Netty线程模型源码分析
查看>>
非常的好的协同过滤入门文章(ZZ)
查看>>
数据结构:哈希表
查看>>
markdown 基本语法
查看>>
tensorflow之tf.slice()
查看>>
Python高阶函数-闭包
查看>>
Windows下安装Redis
查看>>
Ubuntu 12.04 部署 PostGIS 2.1
查看>>
手机web——自适应网页设计(html/css控制)
查看>>
*[codility]CartesianSequence
查看>>
Hadoop1重新格式化HDFS
查看>>