This is actually part of the implementation of Thread.
In principle, you can think of each Thread instance having a Map, where the ThreadLocal object instance (of which there is only one) is the key and the value associated to it is the value.
The static instance of ThreadLocal does not hold the value at all, it is just a marker for the Thread to look it up again (the Thread stores the value).
So
userThreadLocal.get();
is something like
currentThread.privateMapOfThreadLocalValues.get(userThreadLocal);