类ThreadLocal
提供线程本地变量。它与普通变量的区别在于,在不同的线程访问ThreadLocal
(通过get
或set
方法)拥有自己的独立副本。ThreadLocal
实例一般用private static
修饰。
1.ThreadLocal用法 1.1 ThreadLocal常用方法 1 2 3 4 5 6 7 8 public T get () ;public void set (T value) ;public void remove () ;
1.2 ThreadLocal使用案例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public class ThreadLocalTest { private static ThreadLocal<String> threadLocal = new ThreadLocal<>(); public static void main (String[] args) { threadLocal.set("hello world" ); Thread thread = new Thread(() -> { System.out.println("thread: " + threadLocal.get()); }); thread.start(); System.out.println("main: " + threadLocal.get()); } }
以上实例代码运行输出内容为:
1 2 main: hello world thread: null
代码(2)处设置了主线程的ThreadLocal副本值为hello world,故代码(5)输出为main: hello world; 代码(4)处输出子线程中ThreadLocal副本值,因为在子线程中未进行设置,故输出thread: null。
2.源码分析 2.1 set方法
获取当前Thread
实例t
根据t获取ThreadLocalMap
实例map
如果map不为空,则以this(ThreadLocal对象)为key,value(泛型T)为value存入map
如果map为空,则以this为firstKey,value为firstValue创建ThreadLocalMap
,并赋值给t.threadLocals
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public void set (T value) { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); 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); }
2.2 get方法
获取当前Thread
实例t
根据t获取ThreadLocalMap
实例map
如果map不为空,则以this(ThreadLocal对象)为key获取ThreadLocalMap.Entry
实例e,如果e不为空,则返回e.value
如果map为空,返回setInitialValue
方法的值(方法setInitialValue
返回的是方法initialValue
的返回值)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 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(); } 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; } protected T initialValue () { return null ; }
2.3 ThreadLocalMap
ThreadLocalMap是只适用于管理线程本地变量的定制化的哈希表。
1 2 3 4 5 6 7 8 private Entry getEntry (ThreadLocal<?> key) ;private void set (ThreadLocal<?> key, Object value) ;private void remove (ThreadLocal<?> key) ;
1 2 3 4 5 6 7 8 9 static class Entry extends WeakReference <ThreadLocal <?>> { Object value; Entry(ThreadLocal<?> k, Object v) { super (k); value = v; } }
参考链接: