What is threadlocal? In fact, threadlocal is not a local implementation version of a thread, it is not a thread, but Thread Local variable (thread local variable ). It may be more appropriate to name it threadlocalvar. Threadlocal is a simple function. It provides a copy of the variable value for every thread that uses the variable. Each thread can change its own copy independently, it does not conflict with copies of other threads. From the thread perspective, it seems that every thread has the variable completely. Thread Local variables are not new in Java. In other language compilers (such as ibm xl Fortran), they provide direct support at the language level. Java does not provide direct support at the language level, but provides a threadlocal class to support it. Therefore, the code for compiling local variables of threads in Java is relatively clumsy, this may be one of the reasons why local variables of threads are not widely used in Java.
Threadlocal Design
First, let's look at the threadlocal interface:
Java code
Object get (); // returns the local variable copy of the current thread
Protected object initialvalue (); // returns the initial value of the current thread of the local variable of the thread
Void set (object value); // set the value of the local variable copy of the current thread
Object get (); // returns the local variable copy of the current thread
Protected object initialvalue (); // returns the initial value of the current thread of the local variable of the thread
Void set (object value); // set the value of the local variable copy of the current thread
Threadlocal has three methods, among which initialvalue () is worth noting. This method is a protected method, which is specifically implemented for subclass rewriting. This method returns the initial value of the local variable of the current thread. This method is a delayed call method that is executed only when a thread calls get () or set (object) for 1st times, and only once. The true implementation in threadlocal directly returns a NULL:
Java code
Protected object initialvalue (){
Return NULL;
}
Protected object initialvalue (){
Return NULL;
}
How does threadlocal maintain copies of variables for each thread? In fact, the implementation idea is very simple. There is a map in the threadlocal class, which is used to store copies of the variables of each thread. For example, the following example is implemented:
Java code
Public class threadlocal {
Private map values = collections. synchronizedmap (New hashmap ());
Public object get (){
Thread curthread = thread. currentthread ();
Object o = values. Get (curthread );
If (O = NULL &&! Values. containskey (curthread )){
O = initialvalue ();
Values. Put (curthread, O );
}
Return O;
}
Public void set (Object newvalue ){
Values. Put (thread. currentthread (), newvalue );
}
Public object initialvalue (){
Return NULL;
}
}
Public class threadlocal {
Private map values = collections. synchronizedmap (New hashmap ());
Public object get (){
Thread curthread = thread. currentthread ();
Object o = values. Get (curthread );
If (O = NULL &&! Values. containskey (curthread )){
O = initialvalue ();
Values. Put (curthread, O );
}
Return O;
}
Public void set (Object newvalue ){
Values. Put (thread. currentthread (), newvalue );
}
Public object initialvalue (){
Return NULL;
}
}
Of course, this is not an industrial implementation, but the general idea of threadlocal implementation in JDK is similar to this.
Threadlocal usage
If you want to initialize other values for the thread local variable, You need to implement the threadlocal subclass and override this method. Generally, a internal Anonymous class is used to subclass threadlocal. For example, in the following example, the serialnum class assigns an serial number for each class:
Java code
Public class serialnum {
// The next serial number to be assigned
Private Static int nextserialnum = 0;
Private Static threadlocal serialnum = new threadlocal (){
Protected synchronized object initialvalue (){
Return new INTEGER (nextserialnum ++ );
}
};
Public static int get (){
Return (integer) (serialnum. Get (). intvalue ();
}
}
Public class serialnum {
// The next serial number to be assigned
Private Static int nextserialnum = 0;
Private Static threadlocal serialnum = new threadlocal (){
Protected synchronized object initialvalue (){
Return new INTEGER (nextserialnum ++ );
}
};
Public static int get (){
Return (integer) (serialnum. Get (). intvalue ();
}
}
The use of the serialnum class will be very simple, because the get () method is static, so when you need to obtain the serial number of the current thread, simply call:
Java code
Int serial = serialnum. Get ();
Int serial = serialnum. Get ();
You can.
When the thread is active and the threadlocal object is accessible, the thread holds an implicit reference to the local variable copy of the thread. After the thread finishes running, copies of local variables owned by this thread will become invalid and will be collected by the garbage collector.
Comparison between threadlocal and other synchronization mechanisms
What are the advantages of threadlocal over other synchronization mechanisms? Threadlocal and all other synchronization mechanisms are used to solve the access conflict between the same variable in multiple threads. In normal synchronization mechanisms, the object is used to lock multiple threads to securely access the same variable. At this time, the variable is shared by multiple threads. Using this synchronization mechanism, you need to carefully analyze when to read and write the variable and when to lock an object, there are many locks for releasing this object. All this is because multiple threads share resources. Threadlocal solves the concurrent access of multiple threads from another perspective. threadlocal maintains a copy of the variable bound to the thread for each thread, thus isolating the data of multiple threads, every thread has its own copy of the variable, so there is no need to synchronize the variable. Threadlocal provides a thread-safe shared object. When writing multi-threaded code, you can encapsulate the entire insecure variable into threadlocal, or encapsulate the thread-specific state of the object into threadlocal.
Because threadlocal can hold any type of objects, the value of the current thread using threadlocal get requires forced type conversion. However, with the introduction of templates in the new Java version (1.5), the new threadlocal <t> class that supports template parameters will benefit from this. It can also reduce the forced type conversion and advance some error checks to the compilation period, which will simplify the use of threadlocal to a certain extent.
Summary
Of course, threadlocal cannot replace the synchronization mechanism. The two are different in different problem fields. The synchronization mechanism is used to synchronize concurrent access to the same resource by multiple threads and to facilitate communication among multiple threads. threadlocal is used to isolate data sharing among multiple threads, basically, resources (variables) are not shared among multiple threads. Therefore, synchronization between multiple threads is not required. Therefore, if you need to communicate among multiple threads, use the synchronization mechanism. If you need to isolate the sharing conflicts between multiple threads, you can use threadlocal, this greatly simplifies your program and makes it easier to read and write.
Why is it reprinted?
I have read a lot of things, and the others are repeated. Basically, they all talk about the internal implementation of threadloacal. I think this article is better, but it tells the difference between it and synchronization:
I personally think that threadlocal is used to allow different threads to access different variables at the same time (although not at the same time, synchronization allows different threads to reverse query the same variable at different times.