A thread's ThreadLocalMap
remains reachable as long as the thread is alive. The reference to the map is broken when the thread exits; i.e. before the Thread
becomes unreachable.
Entries in the map are reachable as long as the map is reachable. Entries can be removed from the map explicitly by calling ThreadLocal.remove
... but this doesn't happen automatically.
(Actually, this is not entirely correct. Read on.)
The following comments in the Java 11 version of the code partially address your followup question:
ThreadLocalMap
is a customized hash map suitable only for maintaining thread local values. No operations are exported outside of the ThreadLocal
class. The class is package private to allow declaration of fields in class Thread
. To help deal with very large and long-lived usages, the hash table entries use WeakReferences
for keys. However, since reference queues are not used, stale entries are guaranteed to be removed only when the table starts running out of space.
The keys that this is referring to are WeakReference<ThreadLocal<?>>
.
If the application has a strong (i.e. ordinary) reference to its ThreadLocal
object, any corresponding values in any map for any extant thread will be kept. If the application loses its (strong) reference to the ThreadLocal
, then corresponding values may be removed. This will only occur when:
- there is sufficient memory pressure to cause the
WeakReference
to break, AND
- the specific
ThreadLocalMap
is getting a lot of activity.
(The "running out of space" comment don't entirely line up with what the code does. It seems to be a bit more aggressive than that. Look at the code and make up your own mind. Noting that this is implementation dependent behavior.)
But either way, if the application still has a strongly reachable reference to a ThreadLocal
object, corresponding values in maps won't be nulled ... unless the application does it explicitly.