官方解释:
This class provides thread-local variables. These variables differ from their normal counterparts in that each thread that accesses one (via its {@code get} or {@code set} method) has its own, independently initialized copy of the variable. {@code ThreadLocal} instances are typically private static fields in classes that wish to associate state with a thread (e.g., a user ID or Transaction ID)
该类提供了线程局部 (thread-local) 变量。这些变量不同于它们的普通对应物,因为访问某个变量(通过其 get 或 set 方法)的每个线程都有自己的局部变量,它独立于变量的初始化副本。ThreadLocal 实例通常是类中的 private static 字段,它们希望将状态与某一个线程(例如,用户 ID 或事务 ID)相关联。
ThreadLocal是一个将在多线程中为每一个线程创建单独的变量副本的类;当使用ThreadLocal来维护变量时,ThreadLocal会为每个线程创建单独的变量副本,避免因多线程操作共享变量而导致的数据不一致的情况.
原理:
如何实现线程隔离
我们先看看源码:
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();
}
这里主要用到Thread中的一个ThreadLocalMap类型的变量threadLocals,以当先线程为key获取ThreadLocalMap,再以当前的引用为key,获取entry返回value,若entry为空则初始化value并返回.
初始化value源码:
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;
}
调用initialValue方法获取初始值,然后根据当前线程获取ThreadLocalMap
若ThreadLocalMap不为空,则直接将初始值set进去
如果为空则根据当前线程,创建ThreadLocalMap存入当前引用为key和对应的value
从源码中可以看出为什么ThreadLocal能够实现变量的多线程隔离,其实就是用了一个Map缓存当前线程,要使用的时候从当前线程的ThreadLocal对象中获取即可,key就是当前线程.