Why does ThreadLocal Entry inherit WeakReference? Weak reference GC will be collected? So if it’s recycled, won’t the data be lost?

First of all, we have to take a look at WeakReference’s code, which inherits from Reference. There is a get() method here, and the code is as follows:

Notice this sentence:

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

That is, the referent field will be modified during GC, and it will become null after GC.

Here is the code for Entry:

Notice this sentence:

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.

The reference in the Entry will be null if the ThreadLocal is GC. The Entry is an object, and the value will be null if the reference is GC.

It will not be deleted along with ThreadLocal, or even destroyed at all. The GC thread cannot change the value of reference, so the value must be deleted by itself.

ThreadLocal’s only three public instance member methods, get, set, and remove, actually call the getEntry, set, and remove methods of ThreadLocalMap.

GetEntry can be called to expungeStaleEntry via getEntryAfterMiss; It is possible to set to replaceStaleEntry, to expungeStaleEntry through cleanSomeSlots, to expungeStaleEntry through Rehash to expungeStaleEntries and to expungeStaleEntry Can call to cleanSomeSlots and expungeStaleEntry via replaceStaleEntry; And remove will also go to expungeStaleEntry.

In short, all roads lead to Rome, and most likely it will end up in expungeStaleEntry, which is something the author warned us about in the notes:

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.

The realization of the expungeStaleEntry

This is where the Entry value is set to NULL, and where the Entry in the table in ThreadLocalMap is set to NULL.

ThreadLocal == null; ThreadLocal == null; ThreadLocal = null; The only thing that needs to be GC is the value in the Entry, and ThreadLocal itself is small, with only one threadLocalHashCode inside

Why does an Entry of ThreadLocal inherit a WeakReference?