Transferred from http://lavasoft.blog.51cto.com/62575/51926
I. Overview What is threadlocal? In fact, Threadlocal is not a local implementation version of a thread, it is not a threads, but a threadlocalvariable (thread-local variables). Perhaps it would be more appropriate to name it Threadlocalvar. Thread-local variables (ThreadLocal) are very simple in fact, is to provide a copy of the variable value for each thread that uses the variable, and is a more specific thread binding mechanism in Java, where each thread can independently alter its own copy without conflict with the replica of the other thread. From a thread's point of view, each thread maintains an implicit reference to its thread local variable copy, as long as the thread is active and the ThreadLocal instance is accessible, and all copies of its thread-local instances are garbage collected (unless there are other references to those replicas) after the threads have disappeared. Data accessed through threadlocal is always related to the current thread, that is, the JVM binds a private local instance access space for each running thread, thus providing an isolation mechanism for concurrent access problems that often occur in a multithreaded environment. Threadlocal is how to maintain a copy of a variable for each thread. In fact, the idea of implementation is very simple, in the Threadlocal class has a map, used to store a copy of each thread's variables. To sum up, for multithreading resource sharing problem, synchronization mechanism adopts the way of "changing space with Time", and Threadlocal adopts the way of "changing time in Space". The former provides only one variable, allowing different threads to be queued for access, and the latter provides a variable for each thread so that it can be accessed simultaneously without affecting each other.Second, the API descriptionThreadLocal () creates a thread-local variable. T get () returns the value in the current thread copy of this thread local variable, and creates and initializes the copy if this is the first time the thread calls the method. Protected T InitialValue () returns the initial value of the current thread for this thread local variable. This method is called at most once per thread-local variable is obtained, the first time a thread accesses a variable using the Get () method. If the thread calls the set (T) method before the Get method, then the InitialValue method is not called in the thread. If the implementation returns NULL only, or if the programmer wants to initialize a thread-local variable to a value other than NULL, you must create a subclass for ThreadLocal and override this method. Typically, anonymous inner classes are used. A typical implementation of InitialValue will invoke an appropriate construction method and return the newly constructed object. void Remove () Removes the value of this thread local variable. This may help reduce the storage requirements for thread-local variables. If you access this thread local variable again, it will have its initialvalue by default. void set (T value) sets the value in the current thread copy of this thread local variable to the specified value. Many applications do not require this functionality, and they rely only on the InitialValue () method to set the value of a thread-local variable. The InitialValue method is generally overridden in a program to give a specific initial value.Iii. Typical examples 1, Hiberante Session Tool class Hibernateutil This class is hibernate official document Hibernateutil class, for session management. public class Hibernateutil {private static log = Logfactory.getlog (hibernateutil.class); private static final session Factory sessionfactory; Define Sessionfactory Static {try {////create sessionfactory sessionfactory = new Configuration () by default profile Hibernate.cfg.xml. Configure (). Buildsessionfactory (); The catch (Throwable ex) {Log.error ("initialization sessionfactory failed.) ", ex); throw new Exceptionininitializererror (ex); }//Create a thread local variable session, which is used to save Hibernate session public static final ThreadLocal session = new ThreadLocal (); /** * Get Session * @return Session * @throws hibernateexception/public static session Currentsession () throws Hibe in the current thread Rnateexception {Session S = (session) session.get ();//If the session is not yet open, a new session if (s = = null) {s = = SESSIONFACTORY.O Pensession (); Session.set (s); Save the newly opened session to the thread local variable} return s; public static void CloseSession () throws Hibernateexception {//Get thread local variable and cast to session type Session S = (session) Session.get (); Session.set (NULL); if (s!= null) s.close (); } }
In this class, because there is no InitialValue () method that overrides the Threadlocal, the first time a thread local variable session has its initial value null, and the first call to Currentsession (), the thread local variable's get () method is also null. Therefore, the session was judged, if NULL, then a new session, and saved to the thread local variable session, this step is very critical, this is also "public static final ThreadLocal session = new ThreadLocal () Creates an object session that can be cast as the reason for Hibernate session object. 2. Another instance creates a bean that sets the bean properties through different thread objects to guarantee the independence of the individual thread bean objects.
/** * Created by the IntelliJ idea. * User:leizhimin * date:2007-11-23 * time:10:45:02 * Student/public class Student {private int age = 0;//Ages public int Getage () {return this.age.} public void Setage (int age) {this.age = age;}}
/** * Created by the IntelliJ idea. * User:leizhimin * date:2007-11-23 * time:10:53:33 * Multithreading test Program/public class Threadlocaldemo implements Runnable {//Chuang Build thread local variable studentlocal, in the back you will find to save student object private final static ThreadLocal studentlocal = new ThreadLocal (); public static void Main (string[] agrs) {Threadlocaldemo td = New Threadlocaldemo (); thread T1 = new Thread (TD, "a"); Thread t2 = new Thread (TD, "B"); T1.start (); T2.start (); public void Run () {accessstudent ()}/** * Sample business method, used to test/public void Accessstudent () {//Get the name of the current thread String Currentthre Adname = Thread.CurrentThread (). GetName (); System.out.println (Currentthreadname + "is running!"); Produces a random number and prints Random Random = new Random (); int age = Random.nextint (100); SYSTEM.OUT.PRINTLN ("thread" + Currentthreadname + "set Age to:" + age); Gets a Student object and inserts a random number of ages into the object's properties Student Student = Getstudent (); Student.setage (age); SYSTEM.OUT.PRINTLN ("thread" + Currentthreadname + "The" "The" "The" "the" "+ 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 () {//Gets the local thread variable and casts it 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 to the local thread variable studentlocal student = new Student (); Studentlocal.set (student); return student; } }
Run Result:
A is running! Thread A set age to:76 B is running! Thread B Set age to:27 thread A-a-I-is:76 thread B-i-is:27 thread a second read age is:76 thread B Second Read Age is:27
You can see that a, b two thread age prints at different times in exactly the same value. This program through magical threadlocal, not only to achieve multithreading concurrency, to take into account the security of data.Iv. Summary Threadlocal uses the situation mainly solves the inconsistency problem which the data data in the multithreading produces because of concurrency. Threadlocal provides a copy of the data that is concurrently accessed in each thread and runs the business by accessing the Vice, which results in memory savings that greatly reduce the performance consumption of thread synchronization and reduce the complexity of thread concurrency control. Threadlocal cannot use atomic types, only object types are used. Threadlocal is much simpler to use than synchronized. Both threadlocal and synchonized are used to resolve multithreaded concurrent access. But there is an essential difference between threadlocal and synchronized. Synchronized is the mechanism by which a variable or block of code can only be accessed by one thread at a time. The threadlocal provides a copy of the variable for each thread, so that each thread is not accessing the same object at a given time, isolating multiple threads from data sharing. Synchronized, in contrast, is used to gain data sharing when communicating between multiple threads. Synchronized is used for data sharing between threads, while threadlocal is used for data isolation between threads. Of course, threadlocal does not replace synchronized, which handles different problem domains. Synchronized is used to implement synchronization mechanisms, more complex than threadlocal.v. General steps for the use of threadlocal1, in the multithreaded class (such as the Threaddemo Class), create a Threadlocal object threadxxx, to save the thread between the object that needs to be quarantined processing xxx. 2, in the Threaddemo class, create a method to obtain the data to be quarantined getxxx (), in the method to judge, if the Threadlocal object is null, should be new () an object of the isolation access type, and cast to the type to be applied. 3, in the Threaddemo class of the Run () method, through the GetXXX () method to obtain the data to be manipulated, so as to ensure that each thread corresponds to a data object, at any time the operation of this object. Reference Documentation: JDK official documentation http://www.java3z.com/cwbwebhome/article/article2a/271.html?id=319 Http://www.java3z.com/cwbwebhome /article/article2/2952.html?id=1648