Quickly understand the ThreadLocal class in Java
Recently, I looked at the code of Android framework layer and saw the ThreadLocal class. It's a little strange. I turned to various relevant blogs to read it one by one; I then studied the source code again and found that my understanding was different from that of the previous blog, so I decided to write an article to talk about my understanding. I hope it can play the following roles: - it can dredge the research results and deepen my understanding- It can play the role of throwing bricks and attracting jade, and help interested students dredge their ideas- Share learning experience, communicate and learn with you.
1、 What is ThreadLocal
ThreadLocal is the basic class of Java class library, which is in the package Java Lang below;
The official explanation is as follows: implements a thread local storage, that is, a variable for which each thread has its own value All threads share the same ThreadLocal object,but each sees a different value when accessing it,and changes made by one thread do not affect the other threads. The implementation supports null values.
It roughly means that the local storage mechanism of threads can be implemented. ThreadLocal variable is a variable that different threads can have different values. All threads can share the same ThreadLocal object, but different threads can obtain different values when accessing it, and the change of any thread to it will not affect other threads. Class implementation supports null values (null values can be passed and accessed in set and get methods).
Generally speaking, there are three characteristics:
-Different threads obtain different values when accessing - any thread's change to it will not affect other threads - null is supported
The following examples verify these features respectively. First, define a test class. In this class, we verify the three features mentioned above. Class is defined as follows:
Test. java
Code analysis:
From the definition, we can see that only one ThreadLocal object is declared, and the other three threads (main thread, thread a and thread b) share the same object; then, modify the value of the object in different threads and access the value of the object in different threads, and output the viewing results on the console.
Look at the results:
From the console output results, we can see that there are three null outputs. This is because the object is not assigned before output, which verifies the feature of supporting null; In addition, it can be found that I have modified the value of the object in each thread, but when other threads access the object, it is not the modified value, but the local value of the thread; This also verifies the other two characteristics.
2、 Function of ThreadLocal
As we all know, most of its usage scenarios are multi-threaded programming. As for the specific functions, how to say this and that? I think this can only be defined in a general way, because the definition of the functional attributes of a thing will limit everyone's thinking. For example, the kitchen knife is used to cut vegetables, and many people won't use it to cut watermelon. Here, let's talk about my understanding of its role for reference only. I hope it can be helpful. Let's describe it this way, When a multithreaded program needs some tasks on most threads (that is, part of the code in the run method) during encapsulation, ThreadLocal can be used to wrap thread related member variables in the encapsulation to ensure the exclusive access of threads, and all threads can share a encapsulation object. You can refer to looper in Android. Programmers who can't describe problems in code are not good programmers;
Look at the code: a tool for counting the time-consuming of a section of code in a thread (made to illustrate the problem)
StatisticCostTime. java
Well, the tool design is completed. Now let's use it to count the thread time:
Main. java
After running the code, the output result is like this. Note: the accuracy of the output result is nanosecond
See if the result is different from what we expected. It is found that the result of a should be about B1 + B2. How can it become the same as B2? The answer is that when we define starttime and costtime variables, the original intention is that they should not be shared, but should be exclusive to threads. Here, the variables are shared with the singleton, so when calculating the value of a, in fact, the starttime has been modified by B2, so the same result as B2 is output.
Now let's open the annotated part of statistical costtime and try the declaration method of ThreadLocal. Look at the results:
Ah! This has achieved the expected effect. At this time, some students will say that this can be accessed concurrently. Can I ensure thread safety as long as I use ThreadLocal? The answer is no! First, understand why there are thread safety problems. There are only two situations: 1. You share resources that should not be shared between online processes; 2. You do not guarantee orderly access to resources shared between threads; The former can be solved by "space for time", ThreadLocal (or directly declaring thread local variables), and the latter can be solved by "time for space". Obviously, this is not within ThreadLocal's power.
3、 ThreadLocal principle
The implementation principle is actually very simple. Each read-write operation on the ThreadLocal object is actually a read-write operation on the values object of the thread; To clarify, there is no variable copy creation, because the memory space allocated by the variable is not used to store the t object, but the values of its thread are used to store the t object; Each time we call the ThreadLocal set method in the thread, we actually write the object to the values object corresponding to the thread; When calling the get method of ThreadLocal, it is actually the process of getting the object from the values object corresponding to the thread.
Look at the source code:
Member variable set of ThreadLocal
Member method get of treadlocal
Member method initializevalues of ThreadLocal
Member method values of ThreadLocal
How do you read and write values?
Values exists as the inner class of ThreadLocal; The values include an important array object [], which is the key part of solving the problem. It is used to store various types of treadlocal variables in the thread; So the question is, how do you ensure that you don't get values of other types when you take variables of a certain type? In general, a map will be used to map according to the key value; Yes, that's the idea, but it is not implemented by map here. It is a map mechanism implemented by object []; However, if you want to understand it with map, you can't, because the mechanism is the same; Key actually corresponds to the weak reference of ThreadLocal, and value corresponds to the object we passed in.
Explain how to use object [] to implement the map mechanism (refer to figure 1); it uses the parity of array subscripts to distinguish key and value, that is, the following table stores key in even positions and value in odd numbers. If interested students want to know the implementation of the algorithm, they can study it in depth. I won't elaborate here.
Combined with the first example above, analyze the following storage conditions:
When the program executes, there are three threads, A, B and main, calling name. respectively in the thread. During set(), three identical memory spaces are allocated in the heap area for three thread instances to store values objects. The name reference is used as the key and the specific object is used as the value to store three different objects [] (see the figure below):
4、 Summary
ThreadLocal cannot completely solve the concurrency problem in multithreaded programming. For this problem, different solutions should be selected according to different situations, "space for time" or "time for space".
The biggest function of ThreadLocal is to convert thread shared variables into thread local variables to realize the isolation between threads.
The above is all about quickly understanding ThreadLocal in Java in this article. I hope it will be helpful to you. If there are deficiencies, please leave a message to point out. Thank you for your support.