Different threads can get their own data from the same ThreadLocal object.
ThreadLocal.ThreadLocalMap
Inner class of ThreadLocal. An array with the hash value of the ThreadLocal and the Entry element as the value. Inside ThreadLocalMap, a map-like mapping is implemented. The internal Entry inherits WeakReference
static class Entry extends WeakReference<ThreadLocal<? >>{
/** The value associated with this ThreadLocal. */Object value; Entry(ThreadLocal<? > k, Object v) {super(k); value = v; }}Copy the code
ThreadLocal
The get method
public T get(a) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if(map ! =null) {
ThreadLocalMap.Entry e = map.getEntry(this);
if(e ! =null) {
@SuppressWarnings("unchecked")
T result = (T)e.value;
returnresult; }}return setInitialValue();
}
Copy the code
Set method
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if(map ! =null)
map.set(this, value);
else
createMap(t, value);
}
void createMap(Thread t, T firstValue) {
t.threadLocals = new ThreadLocalMap(this, firstValue);
}
Copy the code
Places to use:
- Android’s Looper Handler MessageQueue is based on this.
- .
Example:
public class Main {
static final ThreadLocal<String> mThreadLocal = new ThreadLocal<>();
public static void main(String[] args) {
new Thread("thread1") {
@Override
public void run(a) {
mThreadLocal.set("value1");
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(currentThread().getName() + " localValue:" + mThreadLocal.get());
}
}.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread("thread2") {
@Override
public void run(a) {
mThreadLocal.set("value2");
System.out.println(currentThread().getName() + " localValue:"+ mThreadLocal.get()); } }.start(); }}Copy the code
Output:
thread2 localValue:value2
thread1 localValue:value1
Copy the code
Even though they are the same ThreadLocal object and both call the same set GET method, the get method must return the value corresponding to the current thread.