The effect to be implemented for a thread-wide shared variable is:
Share variables within the same thread among multiple objects
demo for thread sharing variable not implemented:
Package cn.itcast.heima2;
Import Java.util.HashMap;
Import Java.util.Map;
Import Java.util.Random; public class Threadscopesharedata {private static int data = 0;//private static Map<thread, integer> Threaddata
= new Hashmap<thread, integer> ();
public static void Main (string[] args) {//Total 2 threads for (int i=0;i<2;i++) {//Start a thread new threads (new Runnable () {
@Override public void Run () {data = new Random (). Nextint ();
System.out.println (Thread.CurrentThread (). GetName () + "has put data:" + data);
The current thread is placed into the map with the key value, and the respective data//Threaddata.put (Thread.CurrentThread ()) is taken from the respective thread when the value is taken;
New A (). get ();
New B (). get ();
}). Start ();
The static class a{public void Get () {//INT data = Threaddata.get (Thread.CurrentThread ());
System.out.println ("A from" + Thread.CurrentThread (), getName () + "Get data:" + data); The 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:
By printing out the results can be seen, when the Thread-0 obtained a random number, modified the value of data, while sleeping, Thread-1 obtained a random number, also modified the value of data, and then Thread-1 called the static internal Class A and B of the Get method, In fact, the data at this time is already the random number Thread-1 got.
Of course, we can control the running of the thread by adding synchronized lock. Thread-1 cannot modify the value of data until Thread-0 has finished running the method.
In addition, there are several other ways to get the true value given by the thread run-time variable.
thread-wide shared variable implementations:
Map Implementation Method:
Package cn.itcast.heima2;
Import Java.util.HashMap;
Import Java.util.Map;
Import Java.util.Random; public class Threadscopesharedata {private static map<thread, integer> threaddata = new Hashmap<thread, inte
Ger> ();
public static void Main (string[] args) {//Total 2 threads for (int i=0;i<2;i++) {//Start a thread new threads (new Runnable () {
@Override public void Run () {int data = new Random (). Nextint ();
System.out.println (Thread.CurrentThread (). GetName () + "has put data:" + data);
The current thread is placed into the map with the key value, and the respective data is Threaddata.put (Thread.CurrentThread ()) according to the respective thread when the value is taken;
New A (). get ();
New B (). get ();
}). Start ();
The static class a{public void Get () {int data = Threaddata.get (Thread.CurrentThread ());
System.out.println ("A from" + Thread.CurrentThread (), getName () + "Get data:" + data);
The 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:
threadlocal Way:
Package cn.itcast.heima2;
Import Java.util.Random;
public class Threadlocaltest {
private static threadlocal<integer> x = new threadlocal<integer> ();
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);
New A (). get ();
New B (). Get (),
}
}). Start ();
}
Static class a{public
void Get () {
int data = X.get ();
System.out.println ("A from" + Thread.CurrentThread (). GetName ()
+ "Get data:" + data);
}
Static class b{public
void Get () {
int data = X.get ();
System.out.println ("B from" + Thread.CurrentThread (). GetName ()
+ ' Get data: + Data ';
}}
}
The problem: A threadlocal represents a variable, so one can only put one data, and if you have two variables to share within a thread, define two threadlocal. The following are the solutions:
Extended Mode-handles objects in a single case:
Package cn.itcast.heima2;
Import Java.util.Random;
public class Threadlocaltest {//mode one//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);
Mode one ThreadLocal//x.set (data);
Mode two new object way, put multiple attributes into the object//Mythreadscopedata MyData = new Mythreadscopedata ();
Mydata.setname ("name" + data);
Mydata.setage (data);
Mythreadscopedata.set (MyData);
Mode three uses the single case Pattern mythreadscopedata.getthreadinstance (). SetName ("name" + data);
Mythreadscopedata.getthreadinstance (). setage (data);
New A (). get ();
New B (). get (); }
). Start (); The static class a{public void Get () {//mode one ThreadLocal//int data = X.get ();//System.out.println ("A from
"+ Thread.CurrentThread (). GetName ()//+" Get data: "+ data);
Mode two new object mode, put multiple attributes into object//Mythreadscopedata MyData = Mythreadscopedata.get ();; System.out.println ("A from" + Thread.CurrentThread (). GetName ()//+ "Getmydata:" + mydata.getname () + "," +/
/Mydata.getage ());
Mode three uses single case mode mythreadscopedata myData = Mythreadscopedata.getthreadinstance (); System.out.println ("A from" + Thread.CurrentThread (). GetName () + "Getmydata:" + mydata.getname () + "," + myd
Ata.getage ());
} Static class b{public void Get () {//INT data = X.get ();
System.out.println ("B from" + Thread.CurrentThread (). GetName ()//+ "Get data:" + data);
Mythreadscopedata myData = Mythreadscopedata.get ();; System.out.println ("B from" + Thread.CurrentThread (). GetName ()//+ "Getmydata:" +Mydata.getname () + "," +//Mydata.getage ());
Mythreadscopedata myData = Mythreadscopedata.getthreadinstance (); System.out.println ("B from" + Thread.CurrentThread (). GetName () + "Getmydata:" + mydata.getname () + "," + myd
Ata.getage ()); Class mythreadscopedata{Private Mythreadscopedata () {} private static Mythreadscopedata instance = null;//
New Mythreadscopedata ();
private static threadlocal<mythreadscopedata> map = new threadlocal<mythreadscopedata> ();
public static/*synchronized*/Mythreadscopedata getthreadinstance () {Mythreadscopedata instance = Map.get ();
if (instance = = null) {instance = new Mythreadscopedata ();
Map.set (instance);
return instance;
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;
}
}
Summary:
Synchronized and the use of threadlocal can solve the above problems, but this is two different ways, synchronized is a lock-dependent mechanism after another execution. Threadlocal maintains a copy of a variable that is bound to the thread for each thread, thus isolating data from multiple threads, each with its own copy of the variable, so there is no need to synchronize the variable.
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.
Of course, threadlocal can not replace the synchronization mechanism, the two problems facing different areas. The synchronization mechanism is to synchronize multiple threads of concurrent access to the same resource, which is an effective way to communicate between multiple threads, while threadlocal is a data-sharing isolation of multiple threads, fundamentally not sharing resources (variables) between multiple threads, so of course there is no need to synchronize multiple threads.
Application of Threadlocal:
At the business logic level, you need to invoke multiple DAO layers, and we need to ensure that the transaction (JDBC Transaction) is using the same database connection. Then how do you make sure that you use the same database connection?