说说ThreadLocal的原理
Framework用到ThreadLocal的地方
Looper使用ThreadLocal
Choreographer使用ThreadLocal
如果当前线程没有Choreograhper对象的话,就会调用initialValue去初始一个Choreographer对象
ThreadLocal原理
每个线程里都有一个thread对象,这个对象里有一个数组table(类似HashMap),
key:WeakReference<ThreadLocal>
value: Looper, Choreographer...
一个应用里可以定义多个threadLocal,每个ThreadLocal都有自己的hash值
//每定义一个ThreadLocal都会初始一个hash值(递增)
private final int hash = hashCounter.getAndAdd(0x61c88647*2);
从threadLocals里查找ThreadLocal(key,value):
threadLocal index = threadLocal的hash%table.length
如果对于某个threadLocal,算出来的index已经有值了,就从这个index开始往后遍历,找到空的位置,放进去,然后返回这个空位置的index
ThreadLocal原理代码解析
int index = hash & values.mask: 取余操作
this.reference == table[index]: 查看index位置上的key(weakReference) 是否和 当前threadLocal对象的reference匹配上
return (T)table[index+1]: 返回threadLocal的value,因为value是在key的下一个位置
这个方法很长,但logic简单,就两件事:
1. 通过threadLocal的initValue() 创建一个新的value
2. 在table里找一个合适的位置来存放key,value对
cleanUp():table里保存的key是threadLocal 的 weakReference,所以就有可能被回收掉,cleanUp方法就是清除已经被回收掉的key,value对
说说ThreadLocal的原理
1. 同一个ThreadLocal对象,在不同线程get返回不同value
2. Thread对象里有张表(数组),保存了ThreadLocal对象的WeakReference到value的映射关系
3. 这张表(table)是怎么实现的?
数组结构(table):[key, value, key, value, key, value, null, null, key, value, null, null,key value]
key: threadLocal对象的WeakReference
每个threadLocal对象有个hash值,这个treadLocal对象在数组中的位置:index = hash % table, 如果index位置已经有值了,就向后遍历找到null的位置放入,并返回后面这个的index
4. 是如何解决hash冲突的?
上面已经回答了
网友评论