ThreadLocal Concept:
Threadlocal is not used to solve the problem of object shared access, but mainly provides methods of saving objects and convenient object access to avoid parameter passing.
Threadlocal is not a thread, but a local variable of thread, and when using threadlocal to maintain variables threadlocal provides a separate copy of the variable for each thread that uses the variable, This means that each thread can change its own copy independently, without affecting the copy of the other thread.
From the thread perspective, the target variable is the local variable of the current thread, which is the meaning of the class name Local.
4 Ways to Threadlocal:
void set (T value) sets the value in the current thread copy of this thread's local variable to the specified value
void Remove () Removes the value of this thread's local variable current thread
Protected T InitialValue () returns the initial value of the current thread for this thread local variable
T get () returns the value in the current thread copy of this thread's local variable
Note: InitValue (), by default, returns NULL. The Get method calls the InitValue method by default when the first call to get is called before the set is called. So if this method is not covered, it may cause the get to return null. Of course, this is not the case if you call a set. But often in multi-threaded situations we cannot guarantee that each thread calls the set before calling get, so it is best to overwrite the initvalue so as not to cause a null pointer exception.
Threadlocal Implementation principle:
How does threadlocal maintain a copy of a variable for each thread? Let's take a look at the source code of Threadlocal:
public class Threadlocal<t> {public T get () {//Gets the current thread, thread T = Thread.CurrentThread (); Gets the threadlocals variable of the current thread Threadlocalmap map = getmap (t); Gets the value of this threadlocal as key from the current thread's threadlocals variable if (map! = null) {Threadlocalmap.entry e = map.getentry (th IS); if (E! = null) return (T) E.value; } return Setinitialvalue (); } private T Setinitialvalue () {T value = InitialValue (); Thread t = Thread.CurrentThread (); Threadlocalmap map = getmap (t); if (map! = null) Map.set (this, value); else Createmap (t, value); return value; The public void set (T value) {//Gets the thread T = Thread.CurrentThread () of the current threads; Gets the threadlocals variable of the current thread Threadlocalmap map = getmap (t); Save the value with this threadlocal key to the current thread's threadlocals variable to go if (map! = null) Map.set (this, value); else CreaTemap (t, value); } threadlocalmap Getmap (Thread t) {return t.threadlocals; } void Createmap (Thread T, T firstvalue) {t.threadlocals = new Threadlocalmap (this, firstvalue); }}
There is a map in the Threadlocal class that stores a copy of a variable without a thread, and the element key in the map is the value of the variable in the thread copy of the thread object value
Example:
Package Cn.com.example;import Java.util.concurrent.executorservice;import java.util.concurrent.executors;/** * Created by Jack on 2017/2/13. */public class Threadlocaltest {public static void main (string[] args) {Executorservice Executorservice = Exec Utors.newcachedthreadpool (); for (int i = 0; i < 3; i++) {Executorservice.execute (New threadtest ()); } executorservice.shutdownnow (); }}class ThreadTest implements Runnable {@Override public void run () {for (int i = 0; i < 5; i++) { System.out.println (Thread.CurrentThread (). GetName () + "value=" + threadlocalnumber.get ()); }}}class threadlocalnumber {private static threadlocal<integer> value = new Threadlocal<integer> () { Protected synchronized Integer InitialValue () {return 0; } }; public static void Set () {Value.set (Value.get () + 1); } public static int get () {//In order to test directly in get inside + + Value.set (Value.get () + 1); return Value.get (); }}
Results:
Pool-1-thread-3 value=1pool-1-thread-2 value=1pool-1-thread-1 value=1pool-1-thread-2 value=2pool-1-thread-3 value= 2pool-1-thread-2 value=3pool-1-thread-1 value=2pool-1-thread-2 value=4pool-1-thread-2 value=5pool-1-thread-3 value= 3pool-1-thread-3 value=4pool-1-thread-3 value=5pool-1-thread-1 value=3pool-1-thread-1 value=4pool-1-thread-1 value= 5
From the results of the operation, each thread is used for the respective local variables, and the respective reads and writes are non-interfering.
Java ThreadLocal Understanding