All the answers here are correct, but a little disappointing, as they are somewhat silent as a smart implementation of ThreadLocal . I just watched the source code for ThreadLocal and was pleasantly impressed with how it was implemented.
Naive implementation
If I asked you to implement the ThreadLocal<T> class taking into account the API described in javadoc, what would you do? The initial implementation will most likely be ConcurrentHashMap<Thread,T> using Thread.currentThread() as its key. This will work quite well, but has some disadvantages.
- Competition on the subject -
ConcurrentHashMap - is a pretty smart class, but in the end it should still deal with preventing the rotation of threads from it in any way, and if different threads hit it regularly, it will slow down. - Constantly saves a pointer to both the Thread and the object, even after the completion of Thread and can be GC'ed.
GC compliant implementation
Try again, let's look at the problem of garbage collection using weak links . Working with WeakReferences can be confusing, but it should be enough to use a map constructed in this way:
Collections.synchronizedMap(new WeakHashMap<Thread, T>())
Or, if we use Guava (and we should be!):
new MapMaker().weakKeys().makeMap()
This means that after no one holds the Thread (assuming it is finished), the key / value can be garbage collected, which is an improvement, but still does not address the thread conflict problem, which means that our ThreadLocal not everything what an amazing class. In addition, if someone decided to hold Thread objects after they are finished, they will never be GC'ed, and therefore our objects, even if they are not technically available, will no longer be.
Smart implementation
We thought of ThreadLocal as mapping threads to values, but perhaps this is not the right way to think about it. Instead of thinking of it as matching threads with values ββin each ThreadLocal object, what if we thought of it as matching ThreadLocal objects with values ββin each thread? If each thread stores a mapping, and ThreadLocal just provides a good interface in this mapping, we can avoid all the problems of previous implementations.
The implementation will look something like this:
// called for each thread, and updated by the ThreadLocal instance new WeakHashMap<ThreadLocal,T>()
There is no need to worry about concurrency, because only one thread will ever access this card.
Java developers have a major advantage over us: they can directly develop the Thread class and add fields and operations to it, and exactly what they did.
There are the following lines in java.lang.Thread :
ThreadLocal.ThreadLocalMap threadLocals = null;
Which, as the comment suggests, is indeed a batch-private display of all the values ββtracked by ThreadLocal objects for this Thread . The ThreadLocalMap implementation is not WeakHashMap , but it corresponds to the same main contract, including holding its keys by a weak link.
ThreadLocal.get() then executed as follows:
public T get() { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) { ThreadLocalMap.Entry e = map.getEntry(this); if (e != null) { @SuppressWarnings("unchecked") T result = (T)e.value; return result; } } return setInitialValue(); }
And ThreadLocal.setInitialValue() like this:
private T setInitialValue() { T value = initialValue(); Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) map.set(this, value); else createMap(t, value); return value; }
Essentially, use a map in this thread to hold all of our ThreadLocal objects. Thus, we do not need to worry about the values ββin other Threads ( ThreadLocal can literally only access values ββin the current thread) and therefore has no concurrency problems. In addition, as soon as Thread is completed, its map will automatically be GC'ed, and all local objects will be cleared. Even if a Thread held, ThreadLocal objects are retained by a weak standard and can be cleared as soon as the ThreadLocal object goes out of scope.
Needless to say, I was impressed with this implementation, it pretty elegantly circumvents a lot of concurrency issues (admittedly, taking advantage of being part of the main Java, but it forgives them, since it is such a smart class) and provides fast and thread-safe access to objects that need to be accessed only once by a single thread.
tl; dr ThreadLocal implementation is pretty cool and much faster / smarter than you might think at first glance.
If you liked this answer, you can also rate my (less detailed) discussion of ThreadLocalRandom .
Thread / ThreadLocal code snippets taken from an implementation of Oracle / OpenJDK Java 8 .