1. Thread-Scoped shared variables
1.1 Prelude:
Use a map to implement thread-scoped shared variables
Public classThreadscopesharedata {StaticMap<thread, integer> DataMap =NewHashmap<thread, integer>(); Public Static voidMain (string[] args) { for(inti = 0; I < 2; i++) { NewThread (NewRunnable () {@Override Public voidrun () {intdata =NewRandom (). Nextint ();//get a random integerSystem.out.println (Thread.CurrentThread (). GetName ()+ "Put data" +data); Datamap.put (Thread.CurrentThread (), data); NewA (). get (); NewB (). get (); }}). Start (); } } Static classA { Public voidget () {System.out.println (Thread.CurrentThread (). GetName ()+ "Get Data" +Datamap.get (Thread.CurrentThread ())); } } Static classB { Public voidget () {System.out.println (Thread.CurrentThread (). GetName ()+ "Get Data" +Datamap.get (Thread.CurrentThread ())); } }}
The 1.2 threadlocal class is actually a map
/*** ThreadLocal class here ThreadLocal store a variable, if there are multiple variables, you can first encapsulate multiple variables as an object * *@authorAdministrator **/ Public classThreadlocaltest {Staticthreadlocal<integer> x =NewThreadlocal<> ();// Public Static voidMain (string[] args) {// for(inti = 0; I < 2; i++) { NewThread (NewRunnable () {@Override Public voidrun () {intdata =NewRandom (). Nextint ();//get a random integerSystem.out.println (Thread.CurrentThread (). GetName ()+ "Put data" +data); X.set (data); NewA (). get (); NewB (). get (); }}). Start (); } } Static classA { Public voidget () {System.out.println (Thread.CurrentThread (). GetName ()+ "Get Data" +x.get ()); } } Static classB { Public voidget () {System.out.println (Thread.CurrentThread (). GetName ()+ "Get Data" +x.get ()); } }}
2. Thread-wide sharing of multiple variables, multiple variables can be encapsulated as an object
/*** ThreadLocal class here ThreadLocal store a variable, if there are multiple variables, you can first encapsulate multiple variables as an object * *@authorAdministrator **/ Public classThreadlocaltest {Staticthreadlocal<integer> x =NewThreadlocal<> ();// Public Static voidMain (string[] args) {// for(inti = 0; I < 2; i++) { NewThread (NewRunnable () {@Override Public voidrun () {intdata =NewRandom (). Nextint ();//get a random integerSystem.out.println (Thread.CurrentThread (). GetName ()+ "Put data" +data); X.set (data); Mythreadscopedata MyData= Mythreadscopedata.getthreadinstance ();//gets the object that is bound to the threadMydata.setname ("name" +data); Mydata.setage (data); System.out.println (Thread.CurrentThread (). GetName ()+ "put Object" + "Name:" +mydata.getname () + "," + "Age:" +mydata.getage ()); NewA (). get (); NewB (). get (); }}). Start (); } } Static classA { Public voidget () {System.out.println (Thread.CurrentThread (). GetName ()+ "Get Data" +x.get ()); Mythreadscopedata instance= Mythreadscopedata.getthreadinstance ();//directly gets the object associated with the threadSystem.out.println (Thread.CurrentThread (). GetName () + "Get Object" + "Name:" +instance.getname () + "," + "Age:" +instance.getage ()); } } Static classB { Public voidget () {System.out.println (Thread.CurrentThread (). GetName ()+ "Get Data" +x.get ()); Mythreadscopedata instance= Mythreadscopedata.getthreadinstance ();//directly gets the object associated with the threadSystem.out.println (Thread.CurrentThread (). GetName () + "Get Object" + "Name:" +instance.getname () + "," + "Age:" +instance.getage ()); } }}//Single CaseclassMythreadscopedata {//The instance of the class is thread-related, the design of the class is left to the class itself, as long as the call is natural to the thread-relatedPrivate Staticthreadlocal<mythreadscopedata> map =NewThreadlocal<>(); PrivateMythreadscopedata () {} Public StaticMythreadscopedata getthreadinstance () {//threads are independent of each other, and there is no need to consider synchronizationMythreadscopedata instance =Map.get (); if(Instance = =NULL) {instance=NewMythreadscopedata (); Map.set (instance); } returninstance; } PrivateString name; PrivateInteger age; /** * @returnThe name*/ PublicString GetName () {returnname; } /** * @paramName * The name to set*/ Public voidsetName (String name) { This. Name =name; } /** * @return The Age*/ PublicInteger getage () {returnAge ; } /** * @paramAge * The age to set*/ Public voidsetage (Integer age) { This. Age =Age ; }}
Print results
Thread-1 put data-723086824
Thread-0 put data 772514756
Thread-1 put Object name:name-723086824, age: 723086824
Thread-0 put Object name:name772514756, age:772514756
Thread-0 Get Data 772514756
Thread-1 Get data-723086824
Thread-0 get Object name:name772514756, age:772514756
Thread-1 get Object name:name-723086824, Age: 723086824
Thread-0get Data 772514756
Thread-1get data-723086824
Thread-0 get Object name:name772514756, age:772514756
Thread-1 get Object name:name-723086824, Age: 723086824
Instances of a class are thread-related, the design of the class is left to the class itself, as long as the invocation of nature is a thread-related strust2 The main idea of this design
See Java API
Threadlocal has a remove () method
You can remove the variables associated with the thread
remove()
Removes the current thread's value for this thread-local variable.
Add:
Virtual machine corresponding class Runtime, there is a methodaddShutdownHook(Thread hook)
addShutdownHook(Thread hook)
Registers a new virtual-machine shutdown hook.
For example, you can write a thread that sends a message, and when the virtual machine hangs, it calls the incoming thread, sending a message.
There should also be a mechanism in the thread that can execute a previously registered event before a thread is hung up, or a listener is listening on the state of the thread, thus making callbacks
When you get a notification that the thread hangs, you can remove all the variables related to the thread from the delete
Java threads and concurrent libraries advanced applications-thread-scoped shared data threadlocal class