Impersonation threadlocal class implementation: Thread-scoped shared variables, each thread can only access his or her own, and cannot access other threads.
Package com.ljq.test.thread;
Import Java.util.HashMap;
Import Java.util.Map;
Import Java.util.Random; /** * thread-wide Shared variables * * Three modules shared data, main thread module and AB module * * @author Administrator */public class Threadscopesharedata {//
Ready to share data private static int = 0;
Store each thread corresponds to the data private static Map<thread, integer> threaddata = new Hashmap<thread, integer> (); public static void Main (string[] args) {//Starts two threads for (int i = 0; i < 2; i++) {New Thread new Runnable ( {@Override public void run () {//Now modifies the data in the current thread, giving the modified information int data = new Random (). Next
Int ();
Store thread information and corresponding data Threaddata.put (Thread.CurrentThread (), data);
System.out.println (Thread.CurrentThread (). GetName () + "has put data:" + data);
New A (). get ();
New B (). get ();
}). Start ();
} static class A {public void get () {int data = Threaddata.get (Thread.CurrentThread ()); System.out.println ("A from" + Thread.CurrentThread (), getName () + "Get data:" + data);
} static class B {public void get () {int data = Threaddata.get (Thread.CurrentThread ());
System.out.println ("B from" + Thread.CurrentThread (). GetName () + "Get data:" + data);
}
}
}
Run Result:
The role and purpose of threadlocal:
Used to implement data sharing within a thread, that is, for the same program code, multiple modules share one piece of data while running in the same thread, while another data is shared while running in another thread.
Each thread invokes the set method of the global Threadlocal object, which is equivalent to adding a record to its internal map, which is the respective thread, and value is the values that the respective set method passes in. The Threadlocal.clear () method can be called at the end of a thread, which frees up memory more quickly, without calling or, because the associated threadlocal variable can be automatically released after the thread has finished.
Threadlocal's application scenario:
Order Processing consists of a series of operations: reducing inventory levels, add a water account, modify the general ledger, these operations to be done in the same transaction, usually in the same thread, if the cumulative company receivables operation failed, you should roll back the previous operation, otherwise, submit all operations, This requires that these operations use the same database connection objects, and that the code for these operations is in separate module classes.
Bank transfers consist of a series of operations: reducing the balance of the transfer account and increasing the balance to the account, both of which are to be done in the same transaction, they must use the same database connection object, and the code to transfer and transfer the operation is a method of two different account objects respectively.
For example, Strut2 's Actioncontext, the same piece of code is called by a different thread to run, the code operation of the data is the respective state and data of each thread, for different threads that the GetContext method to get the object is not the same, to the same thread said, Regardless of how many times the GetContext method is invoked and in which module GetContext method is used, the same is obtained.
Experiment case: Define a globally shared threadlocal variable, and then start multiple threads to store a random value in the threadlocal variable, then each thread calls another method of other classes, which reads the value of the threadlocal variable in the method of the multiple classes. You can see that multiple classes share the same data in the same thread.
Implementation of the Threadlocal variable packaging, so that the outside world do not directly manipulate threadlocal variables.
For the encapsulation of basic types of data, this application is relatively rare.
The encapsulation of data for an object type is more common, namely, to have a class create separate instance objects for different threads.
Package com.ljq.test.thread;
Import Java.util.Random; /** * Threadlocal class and application technique * * to encapsulate the thread-wide shared data. Encapsulated into a separate data class that provides a set fetch method * The class is instantiated to provide a way to get the instance object, which is an object that is already encapsulated within the current thread range/PU
Blic class Threadlocaltest {private static threadlocal<integer> x = new threadlocal<integer> (); private static threadlocal<mythreadscopedata> Mythreadscopedata = new Threadlocal<mythreadscopedata> ()
;
public static void Main (string[] args) {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 (). GetName () + "has put data:" + data);
X.set (data);
/* Mythreadscopedata myData = new Mythreadscopedata ();
Mydata.setname ("name" + data);
Mydata.setage (data);
Mythreadscopedata.set (MyData); * * Mythreadscopedata.getthreadinstance (). SetnamE ("name" + data);
Mythreadscopedata.getthreadinstance (). setage (data);
New A (). get ();
New B (). get ();
}). Start ();
The method static class a{public void Get () {int data = X.get () is called by using the object instance within the range of the thread being fetched.
System.out.println ("A from" + Thread.CurrentThread (), getName () + "Get data:" + data);
/* Mythreadscopedata myData = Mythreadscopedata.get (); System.out.println ("A from" + Thread.CurrentThread (). GetName () + "Getmydata:" + mydata.getname () + "," + Myda
Ta.getage ());
* * Mythreadscopedata myData = mythreadscopedata.getthreadinstance (); System.out.println ("A from" + Thread.CurrentThread (). GetName () + "Getmydata:" + mydata.getname () + "," + Myda
Ta.getage ());
The method static class b{public void Get () {int data = X.get () is called by using the object instance within the range of the thread being fetched. System.out.println ("B from" + Thread.CurrentThread (). GetName () + ' get data : "+ data);
Mythreadscopedata myData = Mythreadscopedata.getthreadinstance (); System.out.println ("B from" + Thread.CurrentThread (). GetName () + "Getmydata:" + mydata.getname () + "," + Myda
Ta.getage ()); Class Mythreadscopedata {//Single example private Mythreadscopedata () {}//Provide get instance method without synchronized keyword Each thread takes its own data and does not interfere with the public static/* synchronized */mythreadscopedata getthreadinstance () {//Gets the instance object from the current thread-wide data set myth
Readscopedata instance = Map.get ();
if (instance = = null) {instance = new Mythreadscopedata ();
Map.set (instance);
return instance; ///Save instance object to current thread scope data set private static threadlocal<mythreadscopedata> map = new Threadlocal<mythreadscopeda
Ta> ();
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;
}
}