1.定义
当访问共享的可变数据时,通常需要使用同步,一种避免使用同步的方式是不共享数据。如果仅在单线程里访问数据,那么就不需要使用同步,这种技术被称为线程封闭。
2.分类
2.1 栈封闭
栈封闭是线程封闭的一种特例,在栈封闭中,只能通过局部变量才能访问对象。
2.2 ThreadLocal类
维护线程封闭性的一种更常规方法是使用ThreadLocal,这个类能使线程中的某个值与保存值的对象关联起来。
ThreadLocal对象通过用于防止对可变的单实例变量或者全局变量进行共享。
Thread类中定义了一个ThreadLocal.ThreadLocalMap变量:
ThreadLocal.ThreadLocalMap threadLocals = null;
从ThreadLocal的源码中可以分析出,ThreadLocal包含了一个嵌套类ThreadLocalMap,ThreadLocalMap中包含了一个嵌套类Entry,ThreadLocalMap是存放线程局部变量的数据结构,他是和线程绑定在一起的,存放在ThreadLocal中的变量是和ThreadLocal相关联的。这可以从get()方法中看出:
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();
}
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}
private Entry getEntry(ThreadLocal key) {
int i = key.threadLocalHashCode & (table.length - 1);
Entry e = table[i];
if (e != null && e.get() == key)
return e;
else
return getEntryAfterMiss(key, i, e);
}
private Entry getEntryAfterMiss(ThreadLocal key, int i, Entry e) {
Entry[] tab = table;
int len = tab.length;
while (e != null) {
ThreadLocal k = e.get();
if (k == key)
return e;
if (k == null)
expungeStaleEntry(i);
else
i = nextIndex(i, len);
e = tab[i];
}
return null;
}