简介:
ThreadLocal是一个关于创建线程局部变量的类。通常情况下,我们创建的变量是可以被任何一个线程访问并修改的。而使用ThreadLocal创建的变量只能被当前线程访问,其他线程则无法访问和修改。Synchronized用于线程间的数据共享,而ThreadLocal则用于线程间的数据隔离,锁机制:Synchronized是时间换取空间,ThreadLocal是空间换取时间。也就是说这里面存放的变量都只能被当前线程访问,其他线程干预不了。
源码分析:
/**
* 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).
**/
ThreadLocal的内部有两个关键的静态内部类:ThreadLocalMap(哈希表)和Entry,Entry又是ThreadLocalMap的静态内部类。
其中,ThreadLocalMap和线程绑定,Entry和ThreadLocal<K>对象绑定。
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数据的流程:
- 首先获取到当前线程
- 根据当前线程获取绑定的ThreadLocalMap:
return t.threadLocals;
,threadLocals这个变量在Thread类里面定义。 - 判断map对象是否为null,是:构造一个ThreadLocalMap,把initialValue()这个方法的返回值设置到对应的ThreadLocalMap对象里面,并返回。否:直接从ThreadLocalMap里面取出Entry,然后再从过年Entry里面取出value属性的值。下图是构造函数的内容:
ThreadLocalMap(ThreadLocal<?> firstKey, Object firstValue) {
table = new Entry[INITIAL_CAPACITY];
int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY - 1);
table[i] = new Entry(firstKey, firstValue);
size = 1;
setThreshold(INITIAL_CAPACITY);
}
底层的数据结构是一个Entry数组,也就是哈希表。
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
map.set(this, value);
} else {
createMap(t, value);
}
}
set数据的流程:
- 首先获取到当前线程
- 根据线程获取ThreadLocalMap
- 判断map是否为null,是:构造ThreadLocalMap,在构造方法里面进行赋值,否:直接把值设置进去。
场景:
- 实现线程安全,非线程安全的对象使用ThreadLocal之后就会变得线程安全,因为每个线程都会有一个对应的实例。
- 单个线程上下文信息存储。
随便聊聊
好久没有正式写技术博客了,以前断断续续的在其他地方都有写过,也都没有一直坚持写下去,形成系统。也不想给自己立下什么flag之类的,学习是内在驱动的,说再多也么用。随着时间的流逝,总结一些东西,写下心得体会,感觉越来越重要了,沉下心来继续学习。
网友评论