浅谈ThreadLocal

什么是ThreadLocal

ThreadLocal使用场合主要解决多线程中数据数据因并发产生不一致问题。ThreadLocal为每个线程的中并发访问的数据提供一个副本,通过访问副本来运行业务,这样的结果是耗费了内存,大大减少了线程同步所带来性能消耗,也减少了线程并发控制的复杂度。
其中ThreadLocalMap是ThreadLocal的内部静态类,他的主要构成是Entry,通过Entry来保存数据并且继承弱引用。Entry内部使用ThreadLocal作为Key,使用我们设置的value值作为value,在ThreadLocal 的实现中entry使用的key为ThreadLocal以弱引用的形式存在。

ThreadLocal如何解决hash冲突

ThreadLocal中解决hash冲突的方式是采用线性探测法。即根据初始key的hashcode值确定元素在table中的位置,如果发现这个位置上已经被其他key占用,则利用固定的算法寻找一定步长的下一个位置。依次判断,直至找到能够存放的位置。

ThreadLocal的内存泄漏

ThreadLocalMap中entry中的key使用当前ThreadLocal。如果ThreadLocal没有外部强引用来引用他,那么ThrealLocal会在下次JVM垃圾收集时被回收。这时Entry中的key已经被回收,但是value又是一个强引用不会被垃圾回收器回收。这样ThreadLocal的线程如果一直持续运行,就会出现key为null的value。没有设置remove方法释放掉这个Entry的话,那么这个线程的ThreadLocal中的Entry就会一直与线程共存,value就一直得不到回收。通常线程池中对线程的管理都是采用线程复用的方法,线程的生命周期在线程池中很难结束甚至与JVM的生命周期一致。如果JVM内存本身较少或很多如此的场景同时出现,这样就会发生内存泄漏。所以一定要手动设置remove()。

为什么ThreadLocalMap 中key是弱引用

  1. key是强引用:如果使用ThreadLocal的对象被回收,但是ThreadLocalMap的Entry强引用了ThreadLocal(key就是ThreadLocal)。如果没有手动删除entry以及CurrentThread依然运行的前提下,Entry就不会被回收(Entry中包含了ThreadLocal实例和value),则会导致内存泄漏。
  2. key使用弱引用:事实上,在ThreadLocalMap中的set/getEntry方法中,会对key为null(也即ThreadLocal为null)进行判断,如果key为null的话,就会把value设置为null。这也就意味着使用threadLocal 时,currentThread依然运行的前提下,就算忘记调用remove()方法,弱引用比强引用可以多一层保障:弱引用的ThreadLocal被回收,对应的value在下一次ThreadLocal调用get()/set()/remove()中的任意一个方法的时候会被清除,从而避免内存泄漏。

鸣谢:http://t.csdn.cn/P2WE6

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

黄土地的孩子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值