ThreadLocal take you step by step to read the source code (a) - set method

Foreword

Before the "modern operating system," read the first four chapters, the harvest is still very large, especially in process management chapter made me understand complicated by the operating system is how to control. So, which also led to the creation of this one-source analytical article. AQS was originally intended to write source code parsing, but recent projects tend to be busy, I do not have time to write relatively simple ThreadLocal.

PS: recently looking at the "computer network Xie Xiren ed," I felt before looking absolutely not a book, is how to become so simple, and perhaps this is to enhance the realm of it, if the LOL Dan, there are also simple upgrade to well, ha ha ha ha (I probably still do not comprehend the essence of it).

Simple to use

ThreadLocalThe use is very simple

public class TestThreadLocal {
    private static ThreadLocal<String> local = new ThreadLocal<>();
    private static void print(String t){
        System.out.println(t + ":" + local.get());
    }

    public static void main(String[] args) {
        Thread threadOne = new Thread(() -> {
            local.set("threadOne local variable");
            print("threadOne");
        });
        Thread threadTwo = new Thread(() -> {
            local.set("threadTwo local variable");
            print("threadTwo");
        });
        threadOne.start();
        threadTwo.start();
    }
}
复制代码

The output of this code is

threadOne: threadOne local variable
threadTwo: threadTwo local variable

Code execution flow:

Thread threadOnethrough local.set("threadOne local variable")the internal thread sets a value, then local.get()you can get to this value within the thread.

Thread threadTwoempathy

Why call the same within the two threads local.get()method but can get to different values?

Before explaining this question, we first discuss another issue, by local.set()the value stored in the method set in the end where?

set method

We first look at the java source code, are the chiefs wrote to thin products, with due respect to the big brother!

public void set(T value) {
    Thread t = Thread.currentThread();
    ThreadLocalMap map = getMap(t);
    if (map != null) {
        map.set(this, value);
    } else {
        createMap(t, value);
    }
}
复制代码

Though this is the big brother to write code, but the face of it, is still very simple, ha ha ha ha!

I have to sort out what this code does:

  • First, get to the thread to perform the method, using the code from the above point of view is ThreadOne (we only look at a thread because another thread is the same).
  • The thread is then passed to the getMap(t)method, then we look at the code did what
ThreadLocalMap getMap(Thread t) {
    return t.threadLocals;
}
复制代码

This code returns the thread object threadLocalsvariable.

Nani? ? ? I was surprised that there is this thread object variable?

Yes, it does exist, if you only read Threadthe source code and the like, may indeed put this variable is ignored, because Threadmost of the methods in the class are nothing to do with the variable.

I am using jdk8, so in Threadclass 181 line is to declare the variable.

This variable chiefs also made comments to the effect that: This variable is related to this thread ThreadLocal value. And this map is a ThreaLocal kind of maintenance. Map here refers to ThreadLocalMap .

ThreadLocalMap is a custom Map, the actual use with our HashMap is similar, but with an inner class Entry, the class is a weak reference class, the next one will talk about the get method, put the map here when as a Map we usually use it.

So we can probably answer the question raised above, the value stored in the end where? From here, we know the value is stored in the Threadthread object inside.

Indeed the ThreadLocal ThreadLocalMap value exists there, and map and stored in the thread object inside, so indirectly stored in the thread object inside

Why use Map to save it? I think it should be because a thread object can have a number of ThreaLocalobjects. List can also store multiple values, but use List to save it, we do not know which value should take the time value.

Let's get down to business, continue to look set method

  • It will be determined after obtaining the map:

If the map is not empty, then it will ThreadLocal object as a key value as the value of the parameter, the map by set()setting method.

if (map != null) {
    map.set(this, value);
} else {
    createMap(t, value);
}
复制代码

If the map is empty, then on the map is initialized.

void createMap(Thread t, T firstValue) {
    // 创建一个ThreadLocalMap,并且设置第一个键值对,等同于map.set(this, value)
    // 然后赋值给当前线程对象的threadLocals变量
    t.threadLocals = new ThreadLocalMap(this, firstValue);
}
复制代码

The map ThreadLocal objects as keys, then we can venture to guess that the test code local.get()is to how to get the value of.

  • First get the current thread object
  • Then get threadLocals variables in the current thread
  • Because threadLocals ThreadLocal object as a map to the structure of the key, so we just this (call get () of ThreadLocal objects) are passed as parameters to the map of the get method can obtain the corresponding values.

ThreadLocal the get () is a basic step, but because the value passed in is actually to be weak references, so there will be some different specific implementation. As for weak references I will be back as a separate column is concerned.

in conclusion

We can summarize the points set by the method:

  • ThreadLocal value inside the object is passed in through the Map storage structure to ThreadLocal objects as keys, values ​​are stored as vlaue.
  • Map structure is stored in an internal thread object, so when we get the value of the first to get through the thread object Map, then ThreadLocal as a key to get in the Map value.
  • A plurality of thread object is ThreadLocal objects, but a ThreadLocal objects corresponds to only one value. So if you want to copy multiple global variables in a thread copy, it is necessary to create multiple ThreadLocal objects.

end

Finally finished, tomorrow I'll get method can also write together! If you have questions, you can direct comments section to discuss Oh, all you know. Follow-up will write several columns about the ThreadLocal, including the rest of some of the more important ways, weak references, application scenarios, ThreadLocal how to create a memory leak.

Guess you like

Origin juejin.im/post/5df89774e51d4557ea02b256