如何理解ThreadLocal的Entry继承WeakReference

2023-05-14,

这篇文章主要介绍“如何理解ThreadLocal的Entry继承WeakReference”,在日常操作中,相信很多人在如何理解ThreadLocal的Entry继承WeakReference问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何理解ThreadLocal的Entry继承WeakReference”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

导读:ThreadLocal的Entry为什么要继承WeakReference?弱引用GC的时候会回收?那么回收了,数据不会丢失吗?

首先得看一眼WeakReference的代码,它继承自Reference,这里有个get()方法,代码如下:

注意这一句:

If this reference object has been cleared, either by the program or by the garbage collector, then this method returns null.

也就是说,referent这个字段会在GC时被修改,而它经过GC后会变成null

再看问题中说的这个Entry,代码在这里:

注意这一句:

Note that null keys (i.e. entry.get() == null) mean that the key is no longer referenced, so the entry can be expunged from table.

这时得注意一件事,刚才提到ThreadLocal被GC后Entry中的reference就会变为null,但是呢, Entry毕竟也是个对象,它除了会在GC时被改一下reference以外平平无奇,那么这里的value啥时候销毁呢?

反正不会随着ThreadLocal一起被删就对了,甚至它能不能被销毁都是个问题。GC线程是不可能在改reference时顺便改value的,所以这个value只能是被咱自己删。

那么就来看看ThreadLocal仅有的三个public的实例成员方法,也就是getsetremove,它们三个方法最后实际上会调用ThreadLocalMapgetEntrysetremove这三个方法。

getEntry有可能通过getEntryAfterMiss调到expungeStaleEntryset有可能调到replaceStaleEntry也有可能通过cleanSomeSlots调到expungeStaleEntry也有可能通过rehash调到expungeStaleEntries再调到expungeStaleEntry也有可能通过replaceStaleEntry调到cleanSomeSlotsexpungeStaleEntry;而remove也会调到expungeStaleEntry

总之,条条大路通罗马,最后十有八九会跑到expungeStaleEntry里头,而实际上这件事人家作者写注释的时候其实早就提醒过咱们了:

Note that null keys (i.e. entry.get() == null) mean that the key is no longer referenced, so the entry can be expunged from table.Such entries are referred to as "stale entries" in the code that follows.

expungeStaleEntry的实现

Entryvalue就是在这里被设置为null的,ThreadLocalMap中的table中的Entry也是在这里被设置为null的。

那么弱引用的作用是什么呢,只要去 ThreadLocal的源码搜一下== null就能发现它出现的每一处都是在对reference作判断,这代码里就是通过判断reference来判断Entry还有用没用的,最需要被GC的就是Entry中的value,而ThreadLocal本身是很小的,它里面只有一个threadLocalHashCode而已

到此,关于“如何理解ThreadLocal的Entry继承WeakReference”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注本站网站,小编会继续努力为大家带来更多实用的文章!

《如何理解ThreadLocal的Entry继承WeakReference.doc》

下载本文的Word格式文档,以方便收藏与打印。