Home >Java >javaTutorial >A brief analysis of ThreadLocal principle
ThreadLocal means thread local variables! So what are thread local variables? What's the use of this thing? Is it that you were asked in an interview and you couldn’t tell me anything? Today, let’s take a look at the source code of this product and fundamentally understand what it does.
The relationship between Thread, ThreadLocalMap, and Entry
In fact, after studying his source code implementation, it is actually not as complicated as imagined , the main points are as follows:
1. Java can obtain the current Thread instance object through Thread.currentThread(). Now that we can get the Thread object instance, we can operate the instance (properties), such as setting a value for the Thread object.
2. Each Thread object has a ThradLocalMap instance, which has an array of Entries. The Entry object has two main attributes: value and weak reference to ThreadLocal, where the value attribute is the value setting. It is held by the current thread and is also the core attribute of ThreadLocal:
static class Entry extends WeakReference<ThreadLocal<?>> { /** The value associated with this ThreadLocal. */ Object value; Entry(ThreadLocal<?> k, Object v) { super(k); value = v; } }
Note that Entry inherits from WeakReference, and its key is the ThreadLocal object! (Figure 1)
Combining the two knowledge points 1 and 2, we can know that after we get the Thread object, we can control the ThreadLocalMap object of the current thread object, and then Give the value you want to save to the value attribute of ThreadLocalMap's Entry. The relationship between Thread, ThreadLocalMap, and value can be represented by the following figure (Figure 2):
We can draw this conclusion from the above picture: a Thread object holds a ThreadLocalMap object, and then a ThreadLoalMap object contains multiple ThreadLlocal objects and the value of the thread where the ThreadLocal object is located! ! ! In a nutshell: A Thread object can hold the variable values of multiple ThreadLocal objects
So what is the relationship between ThreadLocal and Thread? How can the two read the value? Below is a brief analysis based on the source code.
The relationship between ThreadLocal and Thread
First look at the set method of ThreadLocal:
public void set(T value) { //获取当前线程 Thread t = Thread.currentThread(); //获取当前线程持有的ThreadLocalMap ThreadLocal.ThreadLocalMap map = getMap(t); //将value设置给threadlocalMap if (map != null) map.set(this, value); else createMap(t, value); }
The set method is very logical and simple (j combined with Figure 2 above See for better understanding):
1. Get the current Thread object through the currentThread method
2. Get the ThreadLoalMap object of the current Thread object
3. Add value together with the ThreadLocal object Form an Entry object yourself and save it in the Entry type array of
ThreadLoalMap.
Let’s take a look at the get method of ThreadLocal:
public T get() { //获取当前线程 Thread t = Thread.currentThread(); //获取当前线程的ThreadLocalMap对象 ThreadLocalMap map = getMap(t); if (map != null) { //获取与ThreadLocal对象想关联的value ThreadLocalMap.Entry e = map.getEntry(this); if (e != null) { @SuppressWarnings("unchecked") //获取值 T result = (T)e.value; return result; } } //为空返回初始化值 return setInitialValue(); }
The overall logic of get can be developed and it is also very simple:
1. Get Current Thread object
2. Get the ThreadLocalMap object of the current Thread object
3. Get the Entry object associated with ThreadLocal from ThreadLocalMap, specifically using ThreadLocal as the key.
4. Get the value attribute of the Entry in step 3 and return it.
By observing the get and set methods as a whole, we can draw the following conclusions: calling the set method of the ThreadLocal object is to add value to the ThreadLocalMap of the Thread object; calling the get method of the ThreadLocal object is to obtain the value from the ThreadLocalMap of the Thread object. The core is to manipulate the ThreadLocalMap object of the Thread object to read and write value. The principle is that simple.
So what is the relationship between different ThreadLocal objects located in different threads and saving values in other threads? It can be clearly described through the following picture:
Example of ThreadLocal usage
We know that in Android there are only A Looper object, so how is it done? It is ThreadLocal that plays a role. Take a look at Looper's prepare method:
//定义一个静态的ThreadLocal变量 static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>(); private static void prepare(boolean quitAllowed) { //一个Thread只能关联一个Looper对象 if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(new Looper(quitAllowed)); }
You can know by observing the prepare method. First, use the get method of sThreadLocal to determine whether the current thread already owns a Looper object. If so, throw an exception. ; If the current thread has not set a Looper object, call the set method of ThreadLocal to initialize a Looper object and hand it to the current thread:
sThreadLocal.set(new Looper(quitAllowed));
This ensures that a thread has only one Looper object.
So far, the principle of ThreadLocal has been basically analyzed. As for how to set and get internally, the blogger has not done too detailed analysis because it is not necessary to understand the working reasons and usage scenarios of ThreadLocal. That’s it.
The above is the detailed content of A brief analysis of ThreadLocal principle. For more information, please follow other related articles on the PHP Chinese website!