What we are learning today is how to achieve the sharing of variable data within the scope of the thread itself, and the various threads are independent from each other, and each one is maintained, that is, what we call the Threadlocal function.
First, the concept
You can store the data that each thread uses with the corresponding thread number in a map collection, and you can implement thread-wide sharing of the same variables by using data from that collection to fetch the corresponding thread's data from that set.
Second, the Code
The run () method inside the runnable executes Thread.CurrentThread () on the thread that corresponds to the previous runnable, so the corresponding Thread.CurrentThread () in A and B Corresponding thread for the runnable in which it resides
Public classThreadscopesharedata {Private StaticMap<thread, integer> threaddata =NewHashmap<thread, integer>(); Public Static voidMain (string[] args) { for(inti=0;i<2;i++){ NewThread (NewRunnable () {@Override Public voidrun () {intdata =NewRandom (). Nextint (); System.out.println (Thread.CurrentThread (). GetName ()+ "has put data:" +data); Threaddata.put (Thread.CurrentThread (), data); NewA (). get (); NewB (). get (); }}). Start (); } } Static classa{ Public voidget () {intdata =Threaddata.get (Thread.CurrentThread ()); System.out.println ("A from" +Thread.CurrentThread (). GetName ()+ "Get data:" +data); } } Static classb{ Public voidget () {intdata =Threaddata.get (Thread.CurrentThread ()); System.out.println ("B from" +Thread.CurrentThread (). GetName ()+ "Get data:" +data); } }}
Third, ThreadLocal
JDK1.5 provides the Threadlocal class to facilitate the implementation of thread-wide data sharing, which acts as a map in the previous (not a map inside), which means that each thread has its own value
A Threadlocal object can only record a shared variable inside a thread, need to record multiple shared data, create multiple Threadlocal objects, or encapsulate the data, and store the encapsulated data object in a Threadlocal object.
The associated threadlocal variable can also be freed automatically after the thread ends, or the Threadlocal.remove () method can be called to free up memory faster.
Code:
Public classThreadlocaltest {Private StaticThreadlocal<integer> ThreadLocal =NewThreadlocal<integer>(); Public Static voidMain (string[] args) {//Start Two threads for(inti = 0; I < 2; i++) { NewThread (NewRunnable () {@Override Public voidrun () {//Create a variable that is private to each thread intdata =NewRandom (). Nextint (100); System.out.println (Thread.CurrentThread (). GetName ()+ "has put data:" +data); //set values to localthreadlocal.set (data); NewA (). get (); NewB (). get (); }}). Start (); } } Static classa{ Public voidget () {intdata =Threadlocal.get (); System.out.println ("A from" +thread.currentthread (). GetName () + "have get data:" +data); } } Static classb{ Public voidget () {intdata =Threadlocal.get (); System.out.println ("B from" +thread.currentthread (). GetName () + "have get data:" +data); } } }
Assuming you need to save more than one value, you can package the values of other properties into a single class, and then set the class to a value of threadlocal.
In the following code, a static variable map is defined inside the class mythreadlocalscopedate to hold all mythreadlocalscopedate created by the thread, and use a singleton so that no matter how many threads create only one Mythreadlocalscopedate object.
Public classThreadlocaltest {Private StaticThreadlocal<integer> ThreadLocal =NewThreadlocal<integer>(); Public Static voidMain (string[] args) {//Start Two threads for(inti = 0; I < 2; i++) { NewThread (NewRunnable () {@Override Public voidrun () {//Create a variable that is private to each thread intdata =NewRandom (). Nextint (100); System.out.println (Thread.CurrentThread (). GetName ()+ "has put data:" +data); //set values to localthreadlocal.set (data); //Gets the Mythreadlocalscopedate instance object for its own threadMythreadlocalscopedate MyData =mythreadlocalscopedate.getthreadinstance (); Mydata.setname ("Name" +data); Mydata.setage (data); NewA (). get (); NewB (). get (); }}). Start (); } } Static classa{ Public voidget () {intdata =Threadlocal.get (); System.out.println ("A from" +thread.currentthread (). GetName () + "have get data:" +data); Mythreadlocalscopedate MyData=mythreadlocalscopedate.getthreadinstance (); System.out.println ("A from" +thread.currentthread (). GetName () + "have get Mythreadlocalscopedate name:" +mydata.getname () + ", Age:" +mydata.getage ()); } } Static classb{ Public voidget () {intdata =Threadlocal.get (); System.out.println ("B from" +thread.currentthread (). GetName () + "have get data:" +data); Mythreadlocalscopedate MyData=mythreadlocalscopedate.getthreadinstance (); System.out.println ("B from" +thread.currentthread (). GetName () + "have get Mythreadlocalscopedate name:" +mydata.getname () + ", Age:" +mydata.getage ()); } } } classmythreadlocalscopedate{//single-case mode PrivateMythreadlocalscopedate () {};//Structuring Method Privatization Private Staticthreadlocal<mythreadlocalscopedate> map =NewThreadlocal<mythreadlocalscopedate> ();//Encapsulation Mythreadlocalscopedate is shared within a thread implementation scope//thinking AB Two threads come over the situation of their own analysis AB all need to own the object is not related so do not need synchronization if there is a relationship need to synchronize Public Static /*synchronized*/mythreadlocalscopedate getthreadinstance () {Mythreadlocalscopedate instance=Map.get (); if(instance==NULL) {instance=Newmythreadlocalscopedate (); Map.set (instance); } returninstance; } PrivateString name; Private intAge ; PublicString GetName () {returnname; } Public voidsetName (String name) { This. Name =name; } Public intGetage () {returnAge ; } Public voidSetage (intAge ) { This. Age =Age ; } }
Resources:
"Multithreaded Video" Zhang Xiaoxiang
Java multithreading improves three: thread-scoped shared variables &threadlocal