前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ThreadLocal总结问题

ThreadLocal总结问题

原创
作者头像
笔头
修改2022-02-16 10:04:02
5870
修改2022-02-16 10:04:02
举报
文章被收录于专栏:Android记忆

前期两篇ThreadLocal相关文章,我们大概了解其运行原理。分别是ThreadLocal浅析深入细节ThreadLocalMap带着问题去学习,加深理解。

相关问题

1.为什么Entry key是弱引用,而value是强引用?

个人理解就是在保证value可使用的情况下,降低内存占用。

我们从源码中可以看出,虽然Entry中key,也就是ThreadLocal,是弱引用,但同时ThreadLocal也是被外部引用的,ThreadLocal既是Entry中的key,也是外部对象实例。

key是弱引用,他的价值体现只有在ThreadLocal外部对象引用计数为0的情况才能体现出来。举一个场景,一个线程中,多个ThreadLocal对象,在他们引用计数不为0的情况下,Entry中的key,也就是ThreadLocal,gc的情况下,是不会被回收的。只有你不想用其中某些ThreadLocal实例了,把他们设为null,这个时候gc,可以回收key。这个不难理解吧。

那为啥value不是弱引用?个人理解,可能你在设置某些ThreadLocal=null时,在后面继续使用该key对应的value,如果value也是弱引用,那也会被回收,数据会出问题。

有人会想,key被回收后,后面get取不到数据,导致数据丢失。我理解是,你都把ThreadLocal设为null了,你还用他?

2.ThreadLocal内存泄漏问题

通过 深入细节ThreadLocalMap 这篇文章,我们知道在set、get方法中都会清理ThreadLocalMap数组,所以正常情况下,不会存在内存泄漏问题。

但是在ThreadLocal在没有外部对象强引用时,发生GC会导致弱引用Key会被回收,后面又没有set、get操作,导致Value不会回收,如果创建ThreadLocal的线程一直持续运行,那么这个Entry对象中的value就有可能一直得不到回收,发生内存泄露。所以当我们完成任务后,最好手动调用下remove方法。

3.ThreadLocalMap和HashMap有什么区别?

HashMap相关知识可以看下 HashMap之扩容 这篇文章文章。

1.结构不同

HashMap 的数据结构是数组+链表,ThreadLocalMap的数据结构仅仅是数组。

2.解决hash冲突方式不同

解决hash冲突,通常是两种方法:链表法和开放地址法。链表法就是将相同hash值的对象组织成一个链表放在hash值对应的槽位;开放地址法是通过一个探测算法,当某个槽位已经被占据的情况下继续查找下一个可以使用的槽位

HashMap解决hash冲突用的是链表法

新添加的 Entry 对象放入 table 数组的 bucketIndex 索引处。

如果 bucketIndex 索引处已经有了一个 Entry 对象,那新添加的 Entry 对象指向原有的 Entry 对象(产生一个 Entry 链)。

如果 bucketIndex 索引处没有 Entry 对象,也就是上面程序代码的 e 变量是 null,也就是新放入的 Entry 对象指向 null,也就是没有产生 Entry 链。

ThreadLocalMap解决hash冲突用的是开放地址法

和HashMap的最大的不同在于,ThreadLocalMap结构非常简单,没有用链表的方式,而是采用线性探测的方式,就是根据初始key的hashcode值确定元素在table数组中的位置,如果发现这个位置上已经有其他key值的元素被占用,则利用固定的算法寻找一定步长的下个位置,依次判断,直至找到能够存放的位置。

ThreadLocalMap使用开放地址法原因

ThreadLocal 往往存放的数据量不会特别大,冲突概率低,单纯数组结构更省空间,同时数组的查询效率也是非常高。

还有其他关于ThreadLocal的问题,后面再继续加。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.为什么Entry key是弱引用,而value是强引用?
  • 2.ThreadLocal内存泄漏问题
  • 3.ThreadLocalMap和HashMap有什么区别?
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档