Threadlocal design and use
2003-12-08 ■ Author: srx81 ■ Source: Forum
As early as Java 1.2 was launched, the Java platform introduced a new support: Java. Lang. threadlocal, giving us the ability to write multithreading.ProgramA new choice is provided. With this tool class, you can easily compile a beautiful multi-threaded program. Although threadlocal is very useful, it seems that there are not many friends who know it and use it.
What is threadlocal?
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. The local variables of the thread are not new to Java.
Invention, in some other language compiler implementations (such as ibm xl Fortran), it provides direct support at the language level. Java does not provide direct support at the language level, but provides a threadlocal class to support it.CodeRelatively clumsy. This may be one reason why local variables in the thread are not well popularized in Java.
Threadlocal Design
First, let's look at the threadlocal interface:
Object get (); // returns the copy of the local variable of the current thread protected object initialvalue (); // returns the initial value of the current thread's local Variable Void set (object value ); // set the local variable copy value 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:
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:
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:
Public class serialnum { // The next serial number to be assignedPrivate 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:
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.