ThreadLocal 的缺点?
ThreadLocal 的缺点?
回答重点
正常情况下使用 ThreadLocal 是没什么问题的,但是如果极端情况下,数据比较多,则可能会出现以下几个问题:
- 内存泄露问题
- ThreadLocal 中的 ThreadLocalMap Hash 冲突用的是线性探测法,效率低
- ThreadLocal 主动清理的开销问题
扩展知识
内存泄漏问题
ThreadLocal 的生命周期和线程的生命周期绑定,线程池中的线程可能被复用,但 ThreadLocal 中的值不会自动清理,导致可能发生内存泄漏。
ThreadLocalMap Hash 冲突
线性探测法,效率低。
可以看到,图上显示的是经过两个遍历找到了空位,假设冲突多了,需要遍历的次数就多了。并且下次 get 的时候,hash 直接命中的位置发现不是要找的 Entry ,于是就接着遍历向后找,所以说这个效率低。
而像 HashMap 是通过链表法来解决冲突,并且为了防止链表过长遍历的开销变大,在一定条件之后又会转变成红黑树来查找,这样的解决方案在频繁冲突的条件下,肯定是优于线性探测法,所以这是一个优化方向。
ThreadLocal 主动清理的开销问题
ThreadLocal 使用了 WeakReference 以保证资源可以被释放,但是这可能会产生一些 Etnry 的 key 为 null,即无用的 Entry 存在。
所以调用 ThreadLocal 的 get 或 set 方法时,会主动清理无用的 Entry,减轻内存泄漏的发生。
这其实等于把清理的开销弄到了 get 和 set 上,万一 get 的时候清理的无用 Entry 特别多,那这次 get 相对而言就比较慢了。
Comments