什么是ThreadLocal
它是一个线程本地变量,访问这个变量的每个线程都会有这个变量的一个本地拷贝(副本),多个线程操作的时候,实际是操作自己本地内存里面的变量,从而起到线程隔离的作用,避免线程安全问题。
如下面的演示程序:
Main.java1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| public class Main { static ThreadLocal<Integer> threadLocal = new ThreadLocal<>(); public static void main(String[] args) throws InterruptedException { Thread thread = new Thread(() -> { System.out.println(threadLocal.get()); threadLocal.set(0); System.out.println(threadLocal.get()); }, "1");
Thread thread2 = new Thread(() -> { System.out.println(threadLocal.get()); threadLocal.set(2); System.out.println(threadLocal.get()); }, "2"); thread.start(); thread.join(); thread2.start(); thread2.join(); }
}
|
它的输出是 null 0 null 2
实现的原理
通过一个Key-Value形式,将当前线程的值存入ThreadLocal中,也就是ThreadLocalMap,每个Thread对象都有一个ThreadLocalMap,Key为ThreadLocal对象,Valueh为需要缓存的值。
ThreadLocal.java1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| 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 T get() { 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; return result; } } return setInitialValue(); }
|
拿到Map
ThreadLocal.java1 2 3
| ThreadLocalMap getMap(Thread t) { return t.threadLocals; }
|
ThreadLocal.java1 2 3
| void createMap(Thread t, T firstValue) { t.threadLocals = new ThreadLocalMap(this, firstValue); }
|
ThreadLoca.java1 2 3 4 5 6 7 8 9 10 11 12 13 14
| 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); } if (this instanceof TerminatingThreadLocal) { TerminatingThreadLocal.register((TerminatingThreadLocal<?>) this); } return value; }
|