Simulation ThreadLocal class implementation: shared variables within the thread range, each thread can only access him, and cannot access other threads.
package com.ljq.test.thread; Import java.util.hashmap; Import java.util.Map; Import java.util.random;/*** Shared variable sharing data, the main thread sharing data, the main thread Module and AB module * @AutHor Administrator * * */Public Class ThreadScopeSharedata {// Prepare the shared data Private Static int Data = 0; // Stall the data of the data corresponding to the data of each thread. , Integer> Threaddata = New HashMap < Thread, Integer> (); Public Static Void Main (String [] ARGS) {// Start two thread for (int i = 0; i <2; I ++) {new thread (new runnNABL D Run () {// Now modify the data in the current thread, give the modification information int data = new random (). NextInt (); // Sloping thread information and corresponding data to threaddata.put (thread.currentThread (), Data); System.out.println (thread.currenThread (). GetName () + "has put data:" + data); new a (). get (); new b (). Get ();}}) .start ();}} Static class a {public void get () {int data = threaddata.get (thread.currentthread ()); Read (). GetName ( ) + "get data:" + data);}} Static class b {public void get () {int Data = threaddata.get (thread.currentthread ()); Read. CurrentThread (). Getname () + "get data:" + data);}}}
Run results:
The role and purpose of ThreadLocal:
For data sharing in threads, that is, for the same program code, multiple modules must be shared when running in the same thread, and another data is shared when running in another thread.
Each thread calls the SET method of the global ThreadLocal object, which is equivalent to adding a record to the internal MAP. Key is their respective threads. Value is the value of their respective set methods. At the end of the thread, you can call the ThreadLocal.clear () method, so that the memory will be released faster, and it is okay to call it because the thread can also automatically release the related ThreadLocal variables.
ThreadLocal's application scenario:
Order processing contains a series of operations: reduce inventory, add a running account account, and modify the general account. These operations must be completed in the same transaction, usually in the same thread. If you fail, you should roll back the previous operation, otherwise, all operations are submitted, which requires that these operations use the same database connection object, and the code of these operations is in different module classes.
Bank transfers include a series of operations: reduce the balance of transferring out of the account and increase the balance of the transfer to the account. These two operations must be completed in the same transaction. They must use the same database connection object, transfer and transfer operations The code is the method of two different account objects.
For example, the ActionContext of Strut2, when the same code is called and run by different threads, the data operated by this code is the status and data of each thread. For different threads, the objects obtained by the getContext method are different. For a thread, no matter how many times calling the getContext method and the GetContext method in which module in which module is the same.
Experimental cases: Define a ThreadLocal variable that is shared global, and then start multiple threads to store a random value to the ThreadLocal variable, and then call the other multiple methods of various other categories. Read this ThreadLocal variable in multiple categories. For the value, you can see that multiple classes share the same data in the same thread.
To encapsulate the ThreadLocal variable, so that the outside world should not directly operate the ThreadLocal variable.
This application is relatively rare for the packaging of basic types of data.
The packaging of object type data is more common, that is, let a certain class create an independent instance object for different threads.
package com.ljq.test.thread; Import Java.util.random; /*** ThreadLocal class and application techniques** Packing the shared data within the thread range and encapsulated it to a separate data class. Methods that provide this class to provide an instance object. The instance object obtained is the object of the currently encapsulated. (> ( ); // Private Static ThreadLocal <mythreadscopedata> MythreadScopedata = New ThreadLocal <mythreadScopedata> (); ) {for (int i = 0; i <2; i ++) {new thread (new runnable () () {@OVERRIDE PUBLIC VOID RUN () {int Data = New Random (). NextInt (); System.out.println (thread.currentthread (). ; x x .set (data); /* MythreadScopedata mydata = new mythreadscopedata (); mydata.SetName ("name" + data); mydata.SetAge (data); (MyData); */ MythreadScopedata.getThreadInstance (). SetName ("name" + data); mythreadscopedata.getthreadInstance (). setage (data); new a (). get (); new b ().}}).} // Use Object instances within the scope of the thread range call the corresponding method Static Class a {Public Void Get () {int Data = x.get (); System.out.println ("A FROM" + Thread.CurrenThread (). GetName ( ) + "Get Data:" + Data); /* MythreadScopedata MyData = MythreadScopedata.get (); System.out.println ("A FROM" + Thread.CurrenThread (). GetName () + "Getmydata:" + MyData. getName () + "," + MyData.getage ()); */ MythreadScopedata mydata = MythreadScopedata.getThreadInstance (); System.out.println ("A FROM" + Thread.cu rrentthread (). Getname () + "GetmyData: " + mydata.getName () +", " + mydata.getage ());}} // Use the corresponding method static class b {public void get () {int data = x .get (); System.out.println ("B FROM" + Thread.CurrenThread (). Getname () + "get data:" + data); mythreadScopedata mydata = mythreadscopeedata.getth ReadinStance (); System.out.println ( "B FROM" + Thread.CurrenThread (). Getname () + "Getmydata:" + MyData.getName () + "," + MyData.getAge ()); Rivate MythreadScopedata ( ) {} // Provide an instance method. Do not add the synchronized keywords to indicate that the threads take their own data, and do not interfere with each other. MythreadScopedata Instance = Map.get (); if (Instance == NULL) {Instance = New MythreadScopedata (); MAP.SET (Instance);} Return Instance;} // The data concentration of the data set in the current thread range Static ThreadLocal <mythreadscopedata> Map = New ThreadLocal <mythreadscopeedata> (); Private String name; Private Int Age; Public String GetName () { Return name;} Public void setname (string name) {this.Name = name;} Public int getage () {Return Age;} Public Void Setage (int Age) {this.age = Age;}}}