ThreadLocal is one of the most frequently asked questions in the Java multithreaded module, and can be asked in a variety of ways, either gradually or in a manner similar to my question.

This article mainly analyzes and understands from the following perspectives

1. What is ThreadLocal

2. How to use ThreadLocal

3, ThreadLocal source code analysis

4. ThreadLocal memory leaks

Let’s take a look at ThreadLocal bit by bit, with these questions in mind. Please forgive me if there is anything wrong, and welcome criticism and correction. The following source code is based on JDK1.8.

What is ThreadLocal

A ThreadLocal is called a thread variable, meaning that the variables that populate a ThreadLocal belong to the current thread and are isolated from other threads. ThreadLocal creates a copy of a variable in each thread, so that each thread can access its own internal copy of the variable. It’s easy to understand from a literal point of view, but not so easy to use from a practical point of view. As a common interview question, the usage scenario is quite rich: 1. When passing objects across layers, using ThreadLocal can avoid multiple passes and break the constraints between layers.

2. Data isolation between threads

3. Conduct transaction operations to store thread transaction information.

4. Database connection and Session management.

Now that you have a general idea about ThreadLocal, let’s see how it works.

How to use ThreadLocal

Since ThreadLocal creates one copy per thread, let’s use an example to verify:

From the result, we can see that each thread has its own local value. We set a sleep time so that another thread can read the current local value in a timely manner. This is the basic use of TheadLocal, isn’t it very simple? So why do you use it more often when you connect to a database?

Above is a database connection management class, we use the database first is establishing a database connection, and then run out after closing, do have a very serious problem, if there is a client frequent use a database, you will need to set up multiple links and close, our servers may be unable to stand, how to do? If you have 10,000 clients, then the server pressure is even greater. ThreadLocal is best, because ThreadLocal creates a copy of the connection in each thread and can be used anywhere within the thread without affecting one another, so there are no thread-safety issues and no significant impact on program performance. Doesn’t work very well. This is a basic case study, followed by an analysis of why ThreadLocal is used when connecting to a database. Let’s look at how ThreadLocal works from a source code perspective.

ThreadLocal source code analysis

In the original example, there were only two methods given: get and set, but there are a few more that we need to pay attention to.



With so many methods, let’s focus on sets and then realize the overall ThreadLocal:

1. Set method



If the map exists, the current thread object t is used as the key, and the object to be stored as the value in the map. If the Map does not exist, initialize one. OK, now that you’re at this point, you’re probably wondering what ThreadLocalMap is and how the getMap method is implemented. With these questions in mind, read on. Let’s start with ThreadLocalMap.

We can see that ThreadLocalMap is essentially a static inner class of ThreadLocal that defines an Entry to hold data and is a weak reference to inheritance. Use ThreadLocal as the key inside the Entry and use the value we set as the value.

There is also a getMap

ThreadLocalMap getMap(Thread t) {

return t.threadLocals;

}
Copy the code


Call current thread T and return the member variable threadLocals from the current thread T. And threadLocals is essentially a ThreadLocalMap.

2. Get method



Get the current thread, then call getMap to get a ThreadLocalMap. If the map is not null, Use the current thread as the key for the Entry of ThreadLocalMap, and then the value as the corresponding value. If not, set an initial value.

How do you set an initial value?



The principle is simple:

3, remove method



Remove it from our map.

OK, actually the internal source code is very simple, now we summarize a wave

(1) Each Thread maintains a reference to ThreadLocalMap

(2) ThreadLocalMap is an internal class of ThreadLocal that uses Entry for storage

(3) The copy created by ThreadLocal is stored in its own threadLocals, which is its own ThreadLocalMap.

(4) The key value of a ThreadLocalMap is a ThreadLocal object and can have multiple ThreadLocal variables, so it is stored in the map

(5) You must set before getting, otherwise a null pointer exception will be reported. Of course, you can also initialize one, but you must override the initialValue() method.

(6) ThreadLocal does not store values itself; it simply acts as a key for the thread to retrieve values from ThreadLocalMap.

OK, now I don’t know if you can understand this from a source point of view, but the key for ThreadLocal is the internal ThreadLocalMap.

ThreadLocal ThreadLocal ThreadLocal ThreadLocal

Any article on ThreadLocal will help you understand the problem of memory leaks. Let’s take a look at the picture below.



The diagram above illustrates the relationship between ThreadLocal and Thread and ThreadLocalMap in detail.

1. Thread has a map called ThreadLocalMap

2. The key of a ThreadLocalMap is a ThreadLocal, and the value is set by ourselves.

ThreadLocal is a weak reference, and when null, it is garbage collected

When ThreadLocalMap is null, it will be collected by the garbage collector. When ThreadLocalMap is null, it will not be collected. The key of ThreadLocalMap is missing, but the value is still there, causing a memory leak.

Solution: After using ThreadLocal, run remove to avoid memory overflow. From: baijiahao.baidu.com/s?id=165379…