Threadlocal Application (Z)

zhaozj2021-02-16  98

Although I know Threadlocal's use, sometimes the problem will be explained, or an example is more explanatory.

Thread-Specific Storage Pattern assumes that there is an interface, after I call CALL, I want to know if there is an error, or what Error happens, then use errno method to investigate. (This premise is a little stupid, but There is often existed in the actual system) Legacysystem.java

Interface Legacysystem {Public Void Call (int parameter); public int errno ();

Here we really do the above Interface, in order to simply, do not do any complex movements here, just pass parameters to Errno

Class Legacysystem IMPLEMENTS Legacysystem {Private Int Errno; Public Void Call (INT Parameter) {Errno = Parameter;} PUBLIC INT Errno () {Return Errno;}}

The above Code is very simple just that the incoming parameter also has a printed action. If you are under Single Thread, the Class above will not have any problems. But when the Legacysystemimpl object is multiple Thread access, then the problem will occur. That is to say. Other Thread calls Call will affect the results of the Errno Method. The main thing is the following two threads to call the first Thread has been calling Call (0), then the second Thread after 5 seconds has always called Call (1) If the value of incoming Call and the value of Errno Method returns, print ??? and call system.exit end main1.java

class Main1 extends Thread {private static LegacySystem system = new LegacySystemImpl (); private int value = 0; public Main1 (int value) {this.value = value;} public void run () {while (true) {System.out. Println (Thread.currentThread (). getname () "Checks."); system.call (value); try {thread.sleep (100);} catch (interruptedExcection e) {} int errno = system.rrno () System.out.println (Thread.currentThread (). GetName () ": value =" value ", errno =" errno; if (value! = Errno) {system.out.println ("? ?? "); system.exit (0);}}} public static void main (string [] args) {new main1 (0) .Start (); try {thread.sleep (5000);} catch (InterruptedException E ) {} new main1 (1) .Start ();}}

The result is the following thread-0 checks.thread-0: value = 0, errno = 0thread-0 checks.thread-0: value = 0, errno = 0thread-0 checks.thread-0: value = 0, errno = 0 (中文) Thread-0 Checks.Thread-0: value = 0, errno = 0thread-0 Checks.thread-1 Checks. ← Thread-1 starts after start ... thread-0: value = 0, errno = 1 ← Results are seven eight bad. ??? So now rewritten as follows proxyLegacySystemProxy.javaclass LegacySystemProxy implements LegacySystem {private ThreadLocal thlocal = new ThreadLocal (); public void call (int parameter) {getImpl () call (parameter);.} Public int errno () {return getImpl () errno ();.} private LegacySystemImpl getImpl () {LegacySystemImpl impl = (LegacySystemImpl) thlocal.get (); if (impl == null) {impl = new LegacySystemImpl (); thlocal.set (impl);} Return IMPL;}}

Java.lang.Threadlocal used here, so that now Thread has its own inherent field (for Thread specific in the field of Specific), in order to make Thread have inherent Legacysystemimpl, use Threadlocal's GET and SET METHOD using Threadlocal. Reading and writing now in the solid field of thread writes a new mainmain2.java

class Main2 extends Thread {private static LegacySystem system = new LegacySystemProxy (); private int value = 0; public Main2 (int value) {this.value = value;} public void run () {while (true) {System.out. Println (Thread.currentThread (). getname () "Checks."); system.call (value); try {thread.sleep (100);} catch (interruptedExcection e) {} int errno = system.rrno () System.out.println (Thread.currentThread (). GetName () ": value =" value ", errno =" errno; if (value! = Errno) {system.out.println ("? ?? "); system.exit (0);}}} public static void main (string [] args) {new main2 (0) .Start (); try {thread.sleep (5000);} catch (InterruptedException E ) {} new main2 (1) .start ();}}

转载请注明原文地址:https://www.9cbs.com/read-14349.html

New Post(0)