ThreadLocal 引用关系模型如下
1、ThreadLocal key为什么要使用弱引用?
原因:通过引用关系模型可以看出
a、栈为强引用、entry的key为弱引用,栈方法执行结束后此时可以正常回收threadlocal对象
b、栈、entry的key都为强引用,栈方法执行结束,线程只要存活threadlocal就会存在强引用无法被回收,如果是线程池中的线程,那么一经放入threadlocal将永远存在直到线程销毁,从而导致内存泄漏
总结:弱引用特点,虽然在一定程度上降低了内存泄漏的风险,但是在线程复用(线程池的场景)中,线程寿命很长,大对象长期不被回收影响系统运行效率与安全(如上图),最终造成内存泄漏,最好的做法还是不使用时,主动调用remove方法移除entry避免内存泄露问题
PS:另外JDK在设计时也考虑到key被收到时导致内存泄漏问题,在调用ThreadLocal中set、remove、rehash时会扫描key为null的entry,并将value置为null,避免内存泄漏,但是这种需要调用threadLocal的这些方法时才能触发,如果此时threadlocal已经被回收了还是会存在内存泄漏问题,最好的还是我们再不使用时,手动调用remove处理
2、Hash冲突解决方式
采用线性探测法,为什么没有使用HashMap中的拉链法,我理解是ThreadLocalMap的定位并不是一个大量数据存储的容器,采用探测法更简单容易维护