The Threadlocal class can be understood as threadlocalvariable (thread-local variables), providing access interfaces or methods such as get and set, which hold a separate copy of each thread that uses the variable. So get always returns the most recent value that the current execution thread sets when it calls the set. Threadlocal<t> can be considered to contain a Map<thread,t> object, and a value specific to that thread is saved.
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.
Analog threadlocal
Copy Code code as follows:
Import java.util.Collections;
Import Java.util.HashMap;
Import Java.util.Map;
public class Simplethreadlocal<t> {
Private Map<thread, t> ValueMap = Collections
. Synchronizedmap (New Hashmap<thread, t> ());
public void Set (T newvalue) {
Valuemap.put (Thread.CurrentThread (), newvalue); The ① key is the thread object, and the value is a copy of the variable for this thread
}
Public T get () {
Thread CurrentThread = Thread.CurrentThread ();
T o = valuemap.get (CurrentThread); ② returns the corresponding variable for this thread
if (o = = null &&!valuemap.containskey (CurrentThread)) {//③ is saved in the map if it does not exist in the map.
o = InitialValue ();
Valuemap.put (CurrentThread, O);
}
return o;
}
public void Remove () {
Valuemap.remove (Thread.CurrentThread ());
}
Protected T InitialValue () {
return null;
}
}
Practical threadlocal
Copy Code code as follows:
Class Count {
Private simplethreadlocal<integer> count = new simplethreadlocal<integer> () {
@Override
Protected Integer InitialValue () {
return 0;
}
};
Public Integer Increase () {
Count.set (Count.get () + 1);
return Count.get ();
}
}
Class Testthread implements Runnable {
Private count Count;
Public Testthread (count count) {
This.count = count;
}
@Override
public void Run () {
TODO auto-generated Method Stub
for (int i = 1; I <= 3; i++) {
System.out.println (Thread.CurrentThread (). GetName () + "T" + I
+ "th\t" + count.increase ());
}
}
}
public class Testthreadlocal {
public static void Main (string[] args) {
Count count = new count ();
thread T1 = new Thread (new Testthread (count));
Thread t2 = new Thread (new Testthread (count));
thread t3 = new Thread (new Testthread (count));
thread T4 = new Thread (new Testthread (count));
T1.start ();
T2.start ();
T3.start ();
T4.start ();
}
}
Output
Copy Code code as follows:
Thread-0 1th 1
Thread-0 2th 2
Thread-0 3th 3
Thread-3 1th 1
Thread-1 1th 1
Thread-1 2th 2
Thread-2 1th 1
Thread-1 3th 3
Thread-3 2th 2
Thread-3 3th 3
Thread-2 2th 2
Thread-2 3th 3