赞
踩
实际上,当我们在多线程环境中使用ThreadLocal
时,虽然每个线程使用的是同一个ThreadLocal
实例(即相同的key
),但由于ThreadLocalMap
是和线程绑定的,因此每个线程都有自己独立的ThreadLocalMap
实例。
ThreadLocal
的get()
和set()
方法会访问当前线程的ThreadLocalMap
,这个映射表以ThreadLocal
实例作为键,与线程特定的值(value
)相关联。由于每个线程都有自己的ThreadLocalMap
,因此每个线程通过同一个ThreadLocal
实例存取的值都是独立的。
这一点可以通过ThreadLocal
的源码来进一步理解。在ThreadLocal
类中,每个线程的ThreadLocalMap
是作为Thread
类的一个字段存在的。当你对ThreadLocal
进行get()
或set()
操作时,它会先获取当前线程(Thread.currentThread()
),然后在当前线程对象内部查找或修改ThreadLocalMap
。
源码示例:
- public class ThreadLocal<T> {
-
- 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();
- }
-
- // 其他方法...
- }
在上面的get()
方法示例中,this
代表当前ThreadLocal
实例,作为映射的键,但是由于getMap(t)
获取的是当前线程的ThreadLocalMap
,所以不同线程看到的映射实际上是不同的。
因此,关键点在于虽然ThreadLocal
实例是共享的,但是每个线程都有自己的ThreadLocalMap
,所以它们保存的值是独立隔离的。这就是ThreadLocal
为何能在多线程环境中保持线程局部变量独立性的原理。
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。