ThreadLocal role and purpose: to share data within the thread, i.e., the same program code, a plurality of modules of data to be shared in the same run a thread when the thread is running in another time and a shared Further data.
For a negative example, when we use a simple type int store thread between shared data, but in another thread we want to share additional copy of the data, the data at this time will cause the phenomenon of confusion, as follows:
package com.zzj.test; import java.util.Random; public class Test { private static int data; public static void main(String[] args) { for(int i = 1; i <= 2; i ++) { new Thread(() -> { data = new Random().nextInt(); System.out.println(Thread.currentThread().getName() + " has get data: " + data); new A().get(); new B().get(); }).start(); } } private static class A{ public void get() { System.out.println("A from " + Thread.currentThread().getName() + " has get data: " + data); } } private static class B{ public void get() { System.out.println("B from " + Thread.currentThread().getName() + " has get data: " + data); } } }
Results are as follows:
And when we use ThreadLocal , it will not confuse the phenomenon of data:
public class Test { private static ThreadLocal<Integer> tl = new ThreadLocal<>(); public static void main(String[] args) { for(int i = 1; i <= 2; i ++) { new Thread(() -> { int data = new Random().nextInt(); System.out.println(Thread.currentThread().getName() + " has get data: " + data); tl.set(data); new A().get(); new B().get(); }).start(); } } private static class A{ public void get() { int data = tl.get(); System.out.println("A from " + Thread.currentThread().getName() + " has get data: " + data); } } private static class B{ public void get() { int data = tl.get(); System.out.println("B from " + Thread.currentThread().getName() + " has get data: " + data); } } }
The results are as follows:
ThreadLocal we find the source code to see its basic operating principles:
public void set(T value) { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) map.set(this, value); else createMap(t, value); } public void remove() { ThreadLocalMap m = getMap(Thread.currentThread()); if (m != null) m.remove(this); } public T get() { T the Thread = Thread.currentThread (); ThreadLocalMap Map = the getMap (T); IF (! Map = null ) { ThreadLocalMap.Entry E = map.getEntry ( the this ); IF (! E = null ) { @SuppressWarnings ( "an unchecked " ) T Result = (T) e.Value; return Result; } } return setInitialValue (); } // through static class variable internal thread binding static class ThreadLocalMap {...}
ThreadLocal basic operation procedure: Each thread calls the global ThreadLocal object set method, which is equivalent to an increase in internal map record, key are the respective thread object, value is passed into the method of the respective set value. At the end of the thread can call ThreadLocal.clear () method, which will free up memory more quickly, do not call will automatically release the associated ThreadLocal variable at the end of the thread.
Conclusion - we combine the above two examples and the source can be seen: