Java教程

JDK源码06

本文主要是介绍JDK源码06,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

ThreadLocal的使用

使用threadLocal提供的set方法将值保存,同时使用get来获取值,在每次使用完ThreadLocal使用remove方法对ThreadLocal进行清理用于防止内存泄露

数据结构及源码


在ThreadLocal中有一个自定义的hash map:ThreadLocalMap,其中使用的是数组来保存值
其中数组的类型是继承weakreference的Entry类型

源码中关于继承weakreference中有这样的说明

To help deal with very large and long-lived usages, the hash table entries use WeakReferences for keys. However, since reference queues are not used, stale entries are guaranteed to be removed only when the table starts running out of space.为了处理非常大的对象和长时间使用的对象,hash table实体使用弱引用来充当map的key,但是如果该值如果不被引用的使用,只有当内存满的时候,GC才会去回收这部分内存

这就是ThreadLocal会发生内存泄露的原因,由于弱引用的原因,会导致null的key对应一个非null的value,此时entry无法释放

从这里可以看出ThreadLocal使用的是循环数组的数据结构

Set方法

replaceStaleEntry(key, value, i)

这个方法的名字翻译过来是替换旧的实例,从中可以大概猜出该方法的用处
其中key是entry中的key,即当前的threadLocal对象;
value是其对应的值;
i是循环数组中key为null的entry在table中的索引的值;

从当前的位置向后查找key为null的entry,即无效的key,或者遇到空槽的位置,此时slotToExpunge = staleSlot

expungeStaleEntry

cleanSomeSlots


进行对数扫描的意思是:如果当前循环数组的长度是16,则每次n向左移一位,即16->8->4->2->1;共循环四次,将其中无效的值清除,到空槽的位置停止扫描

remove

调用ThreadLocalMap中remove方法,其中执行如上文所提到的expungeStaleEntry方法

遇到空槽停止遍历

参考文献

源码篇:ThreadLocal你真的理解透了吗?
ThreadLocal内存溢出代码演示

这篇关于JDK源码06的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!