您的位置:首页 > 其它

ThreadLocal个人理解

2011-03-29 22:48 381 查看
为了加深理解,将最近对ThreadLocal的了解和源码分析记录总结一下。

ThreadLocal可以为线程提供局部变量。使用ThreadLocal的get()方法,可以在当前线程能够访问的类和方法中,得与当前线程相关联的变量值。

不过,线程局部变量并不是由ThreadLocal对象保存维护的,而是保存在相关联的线程中。ThreadLocal对象只是作为一个key,为当前线程提供了

查找局部变量的线索。也就是说,不同的线程,以相同的ThreadLocal对象作为key,可以查找到相关联的变量值。

下面是ThreadLocal源码:

private final int threadLocalHashCode = nextHashCode();
private static AtomicInteger nextHashCode = new AtomicInteger();
private static final int HASH_INCREMENT = 0x61c88647;
private static int nextHashCode() {
return nextHashCode.getAndAdd(HASH_INCREMENT);
}


以上代码用于生成与每个ThreadLocal对象的key,key值存放在threadLocalHashCode变量中。
AtomicInteger类保证了线程安全。


public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}


将当前ThreadLocal对象作为key值,而将与当前线程相关联的变量值作为value,存放在一个map中。

ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}
void createMap(Thread t, T firstValue) {
t.threadLocals = new ThreadLocalMap(this, firstValue);
}


该map保存在当前线程的threadLocals变量中。这个map保存了所有的和该线程关联的局部变量。

public T get() {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null)
return (T)e.value;
}
return setInitialValue();
}


当需要与当前线程相关联的局部变量时,用get()方法取出。从当前线程的threadLocals中取出局部变量map,以当前ThreadLocal为key进行查找。

ThreadLocalMap是ThreadLocal的一个内部类,为局部变量的存储提供数据结构。在ThreadLocalMap内部,数据存储是由一个继承了WeakReference<ThreadLocal>类的Entry类型的数组来实现的,该数组以table作为其变量名。弱引用保证了在table过大的时候,可以将过于陈旧(stale)的Entry回收,而不是报出OutOfMemoryException。并且,ThreadLocalMap提供了一套算法,可以根据当前ThreadLocal对象的threadLocalHashCode值,快速的在table数组中定位。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: