Interviewer: Do you know ThreadLocal? Talk about your understanding of it? (Based on jdk1.8)

ThreadLocal:https://baijiahao.baidu.com/s?id=1653790035315010634&wfr=spider&for=pc

In the multi-threading module of java, ThreadLocal is a knowledge point that is often asked. There are many ways to ask questions. It may be a step-by-step or it may be just like my topic. Therefore, only a thorough understanding is required. No matter how you ask, it is all Can do well.

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 leak problem

Let's take these questions and uncover the veil of ThreadLocal bit by bit. Please forgive me if there are any irregularities, and welcome criticisms and corrections. The following source code is based on jdk1.8.

One, what is ThreadLocal

From the name, we can see that ThreadLocal is called a thread variable, which means that the variable filled in ThreadLocal belongs to the current thread, and the variable is isolated from other threads. ThreadLocal creates a copy of the variable in each thread, so each thread can access its own internal copy variable.

It is very easy to understand from the literal meaning, but from the point of view of actual use, it is not so easy. As a frequently asked point in an interview, the usage scenarios are also quite rich:

1. When transferring objects across layers, using ThreadLocal can avoid multiple transfers and break the constraints between layers.

2. Data isolation between threads

3. Perform transaction operations to store thread transaction information.

4. Database connection, Session session management.

Now that you have a general understanding of ThreadLocal, let’s see how to use it.

Two, how to use ThreadLocal

Since the role of ThreadLocal is to create a copy of each thread, we use an example to verify:

From the results, 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 time.

This is the basic use of TheadLocal, is it very simple? So why is it used more when connecting to the database?

The above is a database connection management class. When we use the database, we first establish a database connection, and then close it after using up. This has a very serious problem. If a client frequently uses the database, then We need to establish multiple links and close them. Our server may be overwhelmed. What should we do? If there are 10,000 clients, the server pressure is even greater.

ThreadLocal is best at this time, because ThreadLocal creates a copy of the connection in each thread, and it can be used anywhere within the thread, and the threads do not affect each other, so that there is no thread safety problem, and it will not Seriously affect program execution performance. Isn't it easy to use.

The above is mainly to explain a basic case, and then analyze why ThreadLocal is used when connecting to the database. Let's analyze the working principle of ThreadLocal from the perspective of source code.

Three, ThreadLocal source code analysis

In the first example, only two methods are given, namely get and set methods. In fact, there are still a few that need our attention.

With so many methods, we mainly look at set, and then we can realize the overall ThreadLocal:

1. Set method

From the set method, we can see that the current thread t is first obtained, and then getMap is called to obtain the ThreadLocalMap. If the map exists, the current thread object t is used as the key, and the object to be stored is stored in the map as the value. If the Map does not exist, initialize one.

OK, at this point, I believe you will have a few doubts, what is ThreadLocalMap, and how the getMap method is implemented. With these questions, continue to look down. Let's look at ThreadLocalMap first.

We can see that ThreadLocalMap is actually a static internal class of ThreadLocal, which defines an Entry to store data, and it is also an inherited weak reference. In Entry, ThreadLocal is used as the key, and the value we set is used as the value.

There is also a getMap

ThreadLocalMap getMap(Thread t) {

return t.threadLocals;

}

Call the current thread t, and return the member variable threadLocals in the current thread t. And threadLocals is actually ThreadLocalMap.

2. Get method

 

Through the introduction of ThreadLocal above, I believe you have a good understanding of this method. First get the current thread, and then call the getMap method to get a ThreadLocalMap. If the map is not null, then use the current thread as the entry key of the ThreadLocalMap, and then the value As the corresponding value, if not, set an initial value.

How to set an initial value?

The principle is simple

3. The remove method

Just remove it from our map.

OK, in fact, 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, which 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 ThreadLocalMap is a ThreadLocal object, and there can be multiple threadLocal variables, so they are stored in the map

(5) Before getting get, you must first set, otherwise a null pointer exception will be reported. Of course, one can also be initialized, but the initialValue() method must be rewritten.

(6) ThreadLocal itself does not store the value, it is only used as a key to allow the thread to obtain the value from the ThreadLocalMap.

OK, now from the source code point of view, I don't know if you can understand it. For ThreadLocal, the key is the internal ThreadLocalMap.

Four, several other points to note in ThreadLocal

As long as the article introduces ThreadLocal, it will help everyone to recognize one point, that is, the memory leak problem. Let's first look at the picture below.

The above picture reveals the relationship between ThreadLocal and Thread and ThreadLocalMap in detail.

1. There is a map in Thread, which is ThreadLocalMap

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

3. ThreadLocal is a weak reference. When it is null, it will be treated as garbage.

4. The point is here. Suddenly our ThreadLocal is null, which means it will be recycled by the garbage collector. But at this time, our ThreadLocalMap has the same life cycle as Thread. It will not be recycled. At this time, a phenomenon has occurred. That is, the key of ThreadLocalMap is gone, but the value is still there, which causes a memory leak.

Solution: After using ThreadLocal, perform the remove operation to avoid memory overflow.

 

Guess you like

Origin blog.csdn.net/zw764987243/article/details/112790207