ThreadLocal What flaws? If the thread pool thread using ThreadLocal will be a problem?

What is ThreadLocal

ThreadLocal thread is a local copy of the variable tools. Mainly for the private copy of the object stored in the thread and the thread to do a mapping, variable between individual threads without disturbing each other, in a highly concurrent scenarios can be achieved without state calls, especially for dependent variable values ​​each thread does not make sense complete scenes operations.

Below shows the internal structure of ThreadLocal

Here Insert Picture Description

From the above chart, we have a glimpse of ThreadLocal core mechanisms:

  • Thread each internal thread has a Map.
  • Map inside thread local storage objects (key) and a copy of the thread variable (value)
  • However, Thread internal Map is maintained by the ThreadLocal, ThreadLocal by the thread responsible for getting and setting variables values ​​to the map.

So for the different threads, each time you get a copy of the value, other threads can not get to a copy of the current thread's value, a copy of the form isolation, without disturbing each other.

ThreadLocalMap

Here Insert Picture Description
ThreadLocalMap is ThreadLocal internal class that does not implement the Map interface, a manner independent of the Map function, its internal Entry also implemented independently.

And the biggest difference is that HashMap, ThreadLocalMap structure is very simple, there is no next reference, that is to say in the way ThreadLocalMap Hash resolve the conflict is not linked list, but 采用线性探测的方式. ( How ThreadLocalMap resolve conflicts? )

In ThreadLocalMap, the Entry is used to store configuration data KV. However Entry in the key can only be ThreadLocal objects, this construction method has been limited Entry is dead.

static class Entry extends WeakReference<ThreadLocal> {
    /** The value associated with this ThreadLocal. */
    Object value;

    Entry(ThreadLocal k, Object v) {
        super(k);
        value = v;
    }
}

注意了!!
Entry inherited from WeakReference ( 弱引用,生命周期只能存活到下次GC前), but Key is only a weak reference types, Value is not weak. ( 问题马上就来了)

Because ThreadLocalMap the key is weak references, and Value is a strong reference. This leads to a problem, ThreadLocal in the absence of strong external object references, when GC occurs weak references Key will be recycled, while the Value will not recover .

When the thread is not over, but ThreadLocal has been recovered, it could cause ThreadLocalMap <null, Object> key-value pairs of thread, cause a memory leak. ( ThreadLocal被回收,ThreadLocal关联的线程共享变量还存在).

How to avoid leakage

To prevent such a situation, we have two means.

  • 1. After use thread shared variables, to show the call ThreadLocalMap.remove way to clear thread of shared variables;

Since Key is weak references, then we need to do then is to be completed when you call the ThreadLocal get (), set () method calls the remove method, the Entry node and Map references relationship removed , so that the entire Entry object GC Roots after the analysis becomes unreachable, the next time GC can be recycled.

  • 2, JDK recommended ThreadLocal defined as private static, such ThreadLocal weak references the problem does not exist.

Reference article: https://www.jianshu.com/p/98b68c97df9b
article Reference: https://www.cnblogs.com/coshaho/p/5127135.html

Guess you like

Origin blog.csdn.net/qunqunstyle99/article/details/94717256