本文全面介绍threadlocal,主要从以下几个方面做介绍
- 是什么
- 应用场景
- 内部实现
是什么
翻译过来,就是线程变量。什么叫线程变量呢,就是说线程保存的变量,其实这个名字,并不能很好的解释其含义,叫threadlocalVariable 更合适些。
保存在线程中的变量,不同于线程中声明的临时变量,这个threadlocal 是保存在线程底层的数据,只要保存了,在本线程的任意位置都可以读取并使用,并且只有本线程可以读取并使用,很好地避免了并发的问题。
应用场景
最常见的就是数据库链接,session 管理等,也有一些不方便使用本地变量的情况。
内部实现
类中提供了三个方法可供调用
1.public T get() { }
2.public void set(T value) { }
3.public void remove() { }
下面我们一个个看
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();
}
其中有一行 ThreadLocalMap.Entry e = map.getEntry(this);
很关键,可以看到这个map 的key 使用的是线程本身(this),这就是说只要有线程,不同的线程就是不同的key,也就是说,map 中只可能取到自己线程保存的变量,这也是并发支持的关键所在。
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 void remove() {
ThreadLocalMap m = getMap(Thread.currentThread());
if (m != null)
m.remove(this);
}
读懂了get之后,set 与 remove 也就相当简单了,只是管理了一个特殊的map,key 为当前线程而已。
总结
在管理数据库链接/session 等场景时,线程之间不可共享的数据,线程变量就体现出其特殊的优势,活用这个变量可以为我们的开发带来巨大的变化,以后会对使用场景做更细致的分析。
网友评论