标签:null value 索引 ThreadLocal 源码 线程 key entry 解析
多线程并发访问临界资源,破坏原子操作,会导致线程安全问题。将公共变量与ThreadLocal进行绑定,线程使用该公共变量时拿到的是在该线程中的副本变量,即将线程中的数据进行了隔离,多个线程能使用该变量但互不影响。
变量值的存放路径为:Thread->ThreadLocalMap->Entry->value,ThreadLocal作为Entry的key,通过key可以拿到value。
1.成员变量
内部类ThreadLocalMap 中的Entry[] table 数组(数据结构),table的长度必须是2的n次方,size表示map中entry的个数,threshold表示扩容阈值。阈值通常为2/3*length。
ThreadLocalMap中内部类Entry的value表示线程存储的副本变量值。Entry继承WeakReference,Entry的key是ThreadLocal,是弱引用,在垃圾回收时被回收。
2.构造方法
无参构造
3.查找元素
1.获取当前执行线程thread。
2.获取线程中的变量threadLocalMap。
3.通过threadLocal在map中获取对应的entry。通过key的hash值找到元素在桶中的位置,特别注意需要对entry key的判断,经常存在entry不为空,key为空的情况(key为弱引用)。
4.返回对应的value值。
4.插入元素
1.同上
2.同上
3.当指定索引处存在值的时候,即发生了hash冲突。(1)若key相同则更新value值,(2)若key为null时,以当前索引为中心,向前后查找一组需要清除的entry对象进行清除操作,前后边界是桶中元素为null。向后查找过程中若存在相同的key则进行替换。若没有找到key,则更新当前索引处entry为新插入的值。(3)否则元素插入的位置是下一个最靠近当前索引的位置。
4.当指定索引处无值的时候直接新增一个entry对象。
5.当没有清除到key=null的entry对象且size>threshold时进行rehash()操作。
6. rehash()操作,清除table中所有key=null的entry对象,
size>0.75threshold时进行扩容。
5.移除元素
1.同上
2.同上
3.将key置为null。
4.清除无效的entry对象(将value置为null)。
6.扩容
1.数组容量变为原来的两倍。
2.清除key=null的entry对象。
3.元素在放入新的数组时,若发生了hash冲突,则元素插入到下一个最近的索引处。
7.清除无效的entry对象
private int expungeStaleEntry(int staleSlot) {}
staleSlot索引处entry对应的key=null。返回值是staleSlot往后entry为null的索引。
1.清除staleSlot索引处的entry对象,
2.进行rehash操作,直到entry为null。staleSlot往后查找,当entry的key=null时,将该处的entry对象置为空,否则当entry现在所在的索引位置i与应当在索引位置h不同,将entry调整到索引h位置,或者最接近h的位置。
MAX_VALUE 发布了4 篇原创文章 · 获赞 3 · 访问量 259 私信 关注标签:null,value,索引,ThreadLocal,源码,线程,key,entry,解析 来源: https://blog.csdn.net/MAX_VALUE/article/details/103999164
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。