1 What is ThreadLocal

What is a ThreadLocal? In practical development, it is often used to bind user information and log numbers. Database connections and so on. This way, we can code without affecting the business logic by passing parameters. As the name suggests, it simply binds data to the current thread for subsequent operations.

Since data is bound to the current thread, the most convenient and efficient way to store data is to store key-value hash. Unlike the implementation of HashMap, however, it provides a separate Map class called ThreadLocalMap, which has similar functionality to HashMap, except that its KEY uses weak references (only weak references are reclaimed as long as GC scans for them).

static class ThreadLocalMap {
        static class Entry extends WeakReference<ThreadLocal<? >>{
            /** The value associated with this ThreadLocal. */Object value; Entry(ThreadLocal<? > k, Object v) {super(k); value = v; }}}Copy the code

Why is the KEY of ThreadLocalMap designed to be a weak reference

Why do ThreadLocalMap and HashMap have different keys and are designed to be weak references? Let’s break it down:

  • A HashMap is used by programmers to store all kinds of data. ThreadLocalMap is a class with a Default static access modifier that stores data (its attributes) only for threads.

  • To help deal withvery large and long-lived left, the hash table entries use WeakReferences for keys. To explain: Weak references are used to help handle large and long-lived object usage.

So by summarizing these two points, we know that. A ThreadLocalMap is not used externally like a HashMap and can be considered a thread-private Map, which means that if a ThreadLocalMap uses a HashMap instead of weak references in the case of a long thread lifetime. Application stack overflow can occur when a Map is loaded with large objects and values and the k-V is not removed manually in a timely manner. With weak references, however, there is no need for the programmer to manually remove the k-v when there are no other strong references, which reduces the risk of stack overflows to some extent (if the keys are externally strong references, that is not the case).

3 Why does ThreadLocal leak memory

Because of the use of weak references, it is possible to cause what is often referred to on the Internet as a memory leak? Let’s start with how this memory leak came about. The diagram below:

If an instance of ThreadLocal is set to NULL, the instance is later reclaimed. At this point, ThreadLocal (ThreadLocalMap) has only one weak reference to the key, indicating that the key will be reclaimed during GC. When we recycle, we find that the value V is left in the Map and cannot be retrieved or deleted. This is known as a memory leak problem.

However, we also found that ThreadLocalMap was reclaimed as long as the thread was destroyed, which solved the thread leak problem. But if the thread lives for a long time then it’s in trouble. Another situation is when thread pools are used. We all know that threads in a thread pool are reused, so if a thread that sets ThreadLocal does not clean up its previous Settings, it is likely to reuse the wrong data later. So, the ThreadLocal class provides a method to unbind data, the Remove method.

  public void remove(a) {
         ThreadLocalMap m = getMap(Thread.currentThread());
         if(m ! =null) {
             m.remove(this); }}Copy the code

4 summarizes

ThreadLocal makes it easy to programmatically bind data to the current thread without using methods to pass parameters, simply fetching data from ThreadLocal when needed. The KEY of ThreadLocalMap in ThreadLocal uses weak references, which is convenient for threads to clean up weak reference keys in time in the case of long time survival, and to reduce the risk of stack overflow to some extent. However, the use of weak references brings the risk of thread leakage and data errors in the database thread pool scenario. This requires every programmer to use the remove method as soon as ThreadLocal is finished (even if it’s safe to leave some places unremoved, but there’s a lot of code waiting to be written).