Java. lang. ThreadLocal

Source: Internet
Author: User

Java. lang. ThreadLocal
In-depth study of java. lang. ThreadLocal Class 1. What is ThreadLocal? In fact, ThreadLocal is not a local implementation version of a Thread, it is not a Thread, but threadlocalvariable (Thread local variable ). It may be more appropriate to name it ThreadLocalVar. ThreadLocal provides a copy of the variable value for every thread that uses the variable. It is a special thread binding mechanism in Java, is that each thread can independently change its own copy, without conflict with the copies of other threads. From the thread perspective, each thread maintains an implicit reference to its local variable copy, as long as the thread is active and the ThreadLocal instance is accessible. After the thread disappears, all copies of the local instance of the thread will be garbage collected (unless there are other references to these copies ). Data accessed through ThreadLocal is always related to the current thread. That is to say, JVM binds a private local instance access space for each running thread, this provides an isolation mechanism for concurrent access problems that often occur in multi-threaded environments. 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. To sum up, for multi-threaded resource sharing, the synchronization mechanism adopts the "Time for space" approach, while ThreadLocal adopts the "space for Time" approach. The former provides only one copy of the variable, allowing different threads to queue for access, while the latter provides a copy of the variable for each thread. Therefore, the former can be accessed simultaneously without affecting each other. Ii. API description ThreadLocal () creates a local thread variable. T get () returns the value in the current thread copy of the local variable of this thread. If this is the first time the thread calls this method, it is created and initialized. Protected T initialValue () returns the initial value of the current thread of the local variable of this thread. This method can be called at most once each time the thread is accessed to obtain the local variable of each thread, that is, the first time the thread uses the get () method to access the variable. If the thread calls the set (T) method before the get method, the initialValue method is not called in the thread. If this implementation only returns null, if the programmer wants to initialize a local variable of the thread to a value other than null, the programmer must create a subclass for ThreadLocal and override this method. Typically, anonymous internal classes are used. The typical Implementation of initialValue calls an appropriate constructor and returns the newly constructed object. Void remove () removes the value of the local variable of this thread. This may help reduce the need to store local variables in the thread. If you access the local variable of this thread again, it will own its initialValue by default. Void set (T value) sets the value in the current thread copy of the local variable of this thread to the specified value. Many applications do not need this function. They only rely on the initialValue () method to set the value of the local variable of the thread. In programs, the initialValue method is generally rewritten to give a specific initial value. Iii. Typical instance 1. Hiberante's Session tool class HibernateUtil is the HibernateUtil class in the Hibernate official documentation for session management. Public class HibernateUtil {private static Log log = LogFactory. getLog (HibernateUtil. class); private static final SessionFactory sessionFactory; // defines SessionFactory static {
Try {
// Use the default configuration file hibernate. cfg. xml to create SessionFactory
SessionFactory = new Configuration (). configure (). buildSessionFactory ();
} Catch (Throwable ex ){
Log. error ("failed to initialize SessionFactory! ", Ex );
Throw new ExceptionInInitializerError (ex );
}
}
// Create a local thread variable session to save the Hibernate Session
Public static final ThreadLocal session = new ThreadLocal ();/**
* Get the Session in the current thread
* @ Return Session
* @ Throws HibernateException
*/
Public static Session currentSession () throws HibernateException {
Session s = (Session) session. get ();
// If the Session is not enabled, a new Session is created.
If (s = null ){
S = sessionFactory. openSession ();
Session. set (s); // Save the new Session to the local variable of the thread.
}
Return s;
} Public static void closeSession () throws HibernateException {
// Obtain the local variables of the thread and convert them to the Session type forcibly.
Session s = (Session) session. get ();
Session. set (null );
If (s! = Null)
S. close ();
}
} In this class, because the initialValue () method of ThreadLocal is not overwritten, the initial value of the thread local variable session created for the first time is null. When currentSession () is called for the first time, the get () method of the local variable of the thread is also null. Therefore, the session is determined. If it is null, a new Session is created and saved to the local variable session of the thread. This step is critical, this is also the reason why the session of the object created by "public static final ThreadLocal session = new ThreadLocal ()" can be forcibly converted to the Hibernate Session object. 2. Create a Bean in another instance and set Bean attributes through different thread objects to ensure the independence of Bean objects in various threads. /**
* Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2007-11-23
* Time: 10:45:02
* Student
*/
Public class Student {
Private int age = 0; // age public int getAge (){
Return this. age;
} Public void setAge (int age ){
This. age = age;
}
}/**
* Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2007-11-23
* Time: 10:53:33
* Multi-threaded Testing Program
*/
Public class ThreadLocalDemo implements Runnable {
// Create the local thread variable studentLocal. You will find it later to save the Student object.
Private final static ThreadLocal studentLocal = new ThreadLocal (); public static void main (String [] agrs ){
ThreadLocalDemo td = new ThreadLocalDemo ();
Thread t1 = new Thread (td, "");
Thread t2 = new Thread (td, "B ");
T1.start ();
T2.start ();
} Public void run (){
AccessStudent ();
}/**
* The example business method is used for testing.
*/
Public void accessStudent (){
// Obtain the name of the current thread
String currentThreadName = Thread. currentThread (). getName ();
System. out. println (currentThreadName + "is running! "); // Generate a random number and print it
Random random = new Random ();
Int age = random. nextInt (100 );
System. out. println ("thread" + currentThreadName + "set age to:" + age); // gets a Student object and inserts the random number age into the object property.
Student student = getStudent ();
Student. setAge (age );
System. out. println ("thread" + currentThreadName + "first read age is:" + student. getAge ());
Try {
Thread. sleep (500 );
}
Catch (InterruptedException ex ){
Ex. printStackTrace ();
}
System. out. println ("thread" + currentThreadName + "second read age is:" + student. getAge ());
} Protected Student getStudent (){
// Obtain local thread variables and forcibly convert them to the Student type
Student student = (Student) studentLocal. get ();
// When the thread executes this method for the first time, studentLocal. get () must be null.
If (student = null ){
// Create a Student object and save it to the local thread variable studentLocal
Student = new Student ();
StudentLocal. set (student );
}
Return student;
}
} Running result: a is running!
Thread a set age to: 76
B is running!
Thread B set age to: 27
Thread a first read age is: 76
Thread B first read age is: 27
Thread a second read age is: 76
Thread B second read age is: 27 we can see that the values of thread a and thread B are exactly the same at different times. This program uses ThreadLocal to achieve multi-thread concurrency, while ensuring data security. Iv. Summary ThreadLocal usage mainly solves the inconsistency between data in multiple threads due to concurrency. ThreadLocal provides a copy of the data concurrently accessed by each thread and runs the business by accessing the copy. This results in memory consumption, which greatly reduces the performance consumption caused by thread synchronization, it also reduces the complexity of thread concurrency control. ThreadLocal cannot use the atomic type, but can only use the Object type. ThreadLocal is much easier to use than synchronized. Both ThreadLocal and Synchonized are used to solve multi-thread concurrent access. However, ThreadLocal is essentially different from synchronized. Synchronized uses the lock mechanism to allow a variable or code block to be accessed by only one thread at a time. ThreadLocal provides a copy of the variable for each thread, so that each thread does not access the same object at a certain time, thus isolating multiple threads from sharing data. Synchronized, on the contrary, is used to obtain data sharing when multiple threads communicate. Synchronized is used for data sharing between threads, while ThreadLocal is used for data isolation between threads. Of course, ThreadLocal cannot replace synchronized. They process different problem domains. Synchronized is used to implement synchronization mechanism, which is more complex than ThreadLocal. 5. General steps for ThreadLocal use 1. Create a ThreadLocal object threadXxx in a multi-threaded class (such as ThreadDemo class) to save the xxx object to be isolated and processed between threads. 2. In the ThreadDemo class, create a method getXxx () to obtain the data to be isolated, and Judge in the method. If the ThreadLocal object is null, it should be new () an object that isolates the access type and forcibly converts it to the type to be applied. 3. In the run () method of the ThreadDemo class, use the getXxx () method to obtain the data to be operated. This ensures that each thread corresponds to a data object, this object is operated at any time.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.