Abstract: ThreadLocal is a method of ensuring thread insecurity in avoiding multi-threaded access in addition to locking synchronization.

This article is shared from Huawei Cloud Community " 4 Questions to Get ThreadLocal ", author: breakDraw.

Concurrency problems are prone to occur when multiple threads access the same shared variable, especially when multiple threads write to a variable. In order to ensure thread safety, general users need to take additional synchronization measures when accessing shared variables. Thread safety. ThreadLocal is a way to ensure a way to avoid thread insecurity in multi-threaded access in addition to the synchronization method of locking. When we create a variable, if each thread accesses it, all the access is Thread's own variables so that there is no thread insecurity problem.

Q: What are the common usage scenarios of ThreadLocal?

A: Each thread needs to maintain a different copy, but this copy may be stuffed into each thread at a certain moment, but the changes in the copy will no longer be affected by other threads.

A common scenario is the connector management module connectorManager. The connect variables held by each thread are used individually and will not affect each other or need to be locked. The reason is to put it as a copy in each thread, when the thread starts the connection or closes, it does not affect the getConnect method in other threads.

Q: What is the difference between ThreadLocal and Synchronized keywords?
A:

Synchronized is the consumption of time in exchange for data synchronization and non-conflict

ThreadLocal uses space consumption in exchange for non-conflict between data (not involving synchronization)

Q: In what form is TheadLocal stored in each thread? What is the principle

A: This article explains the ThreadLocal source code very well:

Concurrent programming in Java: an in-depth analysis

After reading it, I summarize it in my own words:

  1. When you call a threadlocal.set(value) in a thread, you actually create a new ThralocalMap in the thread, and then put threadLocal as the key and value as the value in the thread's ThralocalMap.
  2. When threadlocal.get() is called in a thread, the value corresponding to this threadLocal is obtained from the threadLocalMap of the thread
    If the get is not available, you can generate a threadLocal default value by customizing the initValue method

See the figure below:
image.png

Q: What error will the following code report? (Example adapted from the article linked above)

public class Test {
    ThreadLocal<String> stringLocal = new ThreadLocal<String>();
 
    public static void main(String[] args) throws InterruptedException {
        final Test test = new Test();
 
        System.out.println(test.getString());
 
        Thread thread1 = new Thread(){
            public void run() {
                System.out.println(stringLocal.get());
            };
        };
        thread1.start();
        thread1.join();
        stringLocal.set("thread0")
        System.out.println(test.getString());
    }
}

In Thread1, a null pointer will be reported, because no set has been done before calling get, and an error will be reported when doing get at this time.

One way is changed to this:

 Thread thread1 = new Thread(){
            public void run() {
                stringLocal.set("thread1")
                System.out.println(stringLocal.get());
            };
        };

The other is to set a default value for stringLocal, which is generally used when the initial value can be derived directly from the thread:

ThreadLocal<String> stringLocal = new ThreadLocal<String>(){;
protected String initialValue() {
return xxx;
};
};

After the correct set, the answer will return to thread0 and thread1, and how to set later, both sides will not affect each other's threadLocal, although it seems that the members in the same Test are used.

Click to follow to learn about Huawei Cloud's fresh technology for the first time~


华为云开发者联盟
1.4k 声望1.8k 粉丝

生于云,长于云,让开发者成为决定性力量