Anatomy of ThreadLocal

Under normal circumstances, the variables we create can be accessed and modified by any thread. This will lead to a series of problems. For example, if two people go to work, if two people share the same account to save money, then some disputes will inevitably arise in the future. The best solution is to assign one to each of them. Account, this way to avoid disputes.

This promotion to threads is to use ThreadLoad to avoid competition between threads.

Principles of ThreadLocal, points to note when using, and what are the application scenarios?

Answer the four main points:

  • What is ThreadLocal?
  • ThreadLocal principle
  • Points to note when using ThreadLocal
  • Application scenarios of ThreadLocal

What is ThreadLocal?

ThreadLocal, the thread local variable. If you create a ThreadLocal variable, then every thread that accesses this variable will have a local copy of this variable. When multiple threads manipulate this variable, they actually manipulate the variables in their own local memory to isolate threads. Function to avoid thread safety issues.

//创建一个ThreadLocal变量
static ThreadLocal<String> localVariable = new ThreadLocal<>();

ThreadLocal principle

ThreadLocal memory structure diagram:

imageIt can be seen from the structure diagram:

  • The Thread object holds a member variable of ThreadLocal.ThreadLocalMap.
  • ThreadLocalMap maintains an array of Entry internally, each entry represents a complete object, the key is the ThreadLocal itself, and the value is the generic value of the ThreadLocal.

It is easier to understand by comparing several key source codes

public class Thread implements Runnable {
 ......
//与此线程有关的ThreadLocal值。由ThreadLocal类维护
ThreadLocal.ThreadLocalMap threadLocals = null;

//与此线程有关的InheritableThreadLocal值。由InheritableThreadLocal类维护
ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
 ......
}

From the source code of the Thread class, we can see that there is a threadLocals and an inheritableThreadLocals variable in the Thread class, both of which are variables of the ThreadLocalMap type.

The key methods set() and get() in ThreadLocal

public void set(T value) {
        Thread t = Thread.currentThread(); //获取当前线程t
        ThreadLocalMap map = getMap(t);  //根据当前线程获取到ThreadLocalMap
        if (map != null)
            map.set(this, value); //K,V设置到ThreadLocalMap中
        else
            createMap(t, value); //创建一个新的ThreadLocalMap
    }
    public T get() {
        Thread t = Thread.currentThread();//获取当前线程t
        ThreadLocalMap map = getMap(t);//根据当前线程获取到ThreadLocalMap
        if (map != null) {
            //由this(即ThreadLoca对象)得到对应的Value,即ThreadLocal的泛型值
            ThreadLocalMap.Entry e = map.getEntry(this);
            if (e != null) {
                @SuppressWarnings("unchecked")
                T result = (T)e.value; 
                return result;
            }
        }
        return setInitialValue();
    }

From the source code, we know that the final variable is stored in the ThreadLocalMap of the current thread, not on Threadlocal.

Each Thread has a ThreadLocalMap, and ThreadLocal can store key-value pairs with ThreadLocal as the key and Object as the value.

Entry array of ThreadLocalMap

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;
        }
    }
}

So how to answer **"The principle of ThreadLocal implementation"**? As follows, it is best to combine the above structure diagram together to explain

  • The Thread class has an instance variable threadLocals of type ThreadLocal.ThreadLocalMap, that is, each thread has its own ThreadLocalMap.
  • ThreadLocalMap maintains an array of Entry internally, each entry represents a complete object, the key is the ThreadLocal itself, and the value is the generic value of the ThreadLocal.
  • When each thread sets a value in ThreadLocal, it stores it in its own ThreadLocalMap, and reads it with a certain ThreadLocal as a reference, and finds the corresponding key in its own map, thus achieving thread isolation.

ThreadLocal memory leak problem

Let's take a look at the reference diagram of TreadLocal:

image

The key used in ThreadLocalMap is a weak reference of ThreadLocal, and the value is a strong reference, as followsimage

Weak reference: As long as the garbage collection mechanism runs, regardless of whether the JVM's memory space is sufficient, the memory occupied by the object will be reclaimed.

Weak references are easier to be recycled. Therefore, if ThreadLocal (Key of ThreadLocalMap) is recycled by the garbage collector, but because the life cycle of ThreadLocalMap is the same as that of Thread, if it is not recycled at this time, this will happen: the key of ThreadLocalMap is gone, and the value is still Now, this will "cause a memory leak problem" . How to "solve the memory leak problem"**? After using the ThreadLocal, call the remove() method in time to release the memory space.

Application scenarios of ThreadLocal

  • Database connection pool
  • Used in session management

At last

  • If you feel that you are rewarded after reading it, I hope to give me a thumbs up. This will be the biggest motivation for me to update. Thank you for your support.
  • Welcome everyone to pay attention to my public account [Java Fox], focusing on the basic knowledge of java and computer, I promise to let you get something after reading it, if you don’t believe me, hit me
  • If you have different opinions or suggestions after reading, please comment and share with us. Thank you for your support and love.

——I am Chuhu, and I love programming as much as you.

image

Guess you like

Origin blog.csdn.net/issunmingzhi/article/details/111614850