基于Android 7.0分析
关键的几个点先列出来
public class ThreadLocal<T> {
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();
}
public void set(T value){
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if(map !=null ){
map.set(this, value);
}else{
createMap(t, value);
}
}
ThreadLocalMap getMap(Thread t){
return t.threadLocals;
}
void createMap(Thread t, T firstValue){
t.threadLocals = new ThreadLocalMap(this, firstValue);
}
}
可以看到核心了,ThreadLocal链接了Thread和ThreadLocalMap
public class Thread implements Runnable{
ThreadLocal.ThreadLocalMap threadLocals = null;
}
所以,ThreadLocal保存的数据是存在线程自身的成员变量ThreadLocal.ThreadLocalMap中的
//ThreadLocal.java
static class ThreadLocalMap{
static class Entry extends WeakReference<ThreadLocal>{
Object value;
Entry(ThreadLocal k, Object v){
super(k);
value = v;
}
}
private Entry[] table;
private Entry getEntry(ThreadLocal key){
int i = key.threadLocalHashCode & (table.length -1);
Entry e = table[I];
if(e!=null && e.get() ==key){
return e;
}
}
private void set(ThreadLocal key, Object value){
Entry[] tab = table;
int len = tab.length;
int i = key.threadLocalHashCode & (lend -1);
for(Entry e = tab[I],e!=null;e=tab[I = nexIndex(I,len)]){
ThreadLocal k = e.get();
if(k==key){
e.value = value;
return;
}
}
....
rehash();
}
}
那我们是怎么使用的呢,我们会先实例化一个ThreadLocal对象,随后在线程调用set(T) or get() @ThreadLocal方法。
从上面可以看出,每个线程都有一个ThreadLocal.ThreadLocalMap对象,其中又有一个数组Entry[],每次进行set/get的时候,会将这个ThreadLocal作为key,保存在线程的ThreadLocal.ThreadLocalMap中,保存的过程是通过将ThreadLocal进行hash取模保存在Entry[]中,如果发生了Hash冲突,就取下一个点位
private static int nextIndex(int I, int len){
return ((I+1 > len)? I+1:0);
}
为了防止内存泄漏,Entry还继承自WeakReference<ThreadLocal>
网友评论