![](https://img.haomeiwen.com/i4930604/b91cea99698d62fa.png)
![](https://img.haomeiwen.com/i4930604/988d9755a0995a6c.png)
![](https://img.haomeiwen.com/i4930604/9e5c251664af3e1c.png)
ThreadLocalMap是Thread里面一个以ThreadLocal为key的map, 因为一个线程可能有多个ThreadLocal
给ThreadLocal实例set值就是
threadLocal.currentThread.threadLocalMap.set(threadLocal,value)
可以看到, ThreadLocal里面只需要一个field(另外一个是辅助的)就是threadLocalHashCode, 用于它在ThreadLocalMap里面当key的时候作为hash码
![](https://img.haomeiwen.com/i4930604/487d56034d1f8402.png)
ThreadLocal除了一个hash值, 就没其他状态了, 具体的值还是由线程各自保管, ThreadLocal只提供方法
内存泄漏
如果 做这样的操作 threadLocal=null
意图是所有的线程里面都用存以这个theadLocal
为key的值了
用软引用避免的 [threadLocal不能垃圾回收]
可以看到 ThreadLocalMap的key是一个弱引用,
这是为了
如果这个ThreadLocal对象已经没有其他引用指向它了,
各个线程里面的ThreadLocalMap不会阻止这个ThreadLocal对象的回收,
就是说, threadLocal=null
这样做的话, 下次垃圾回收会把 threadLocal
这个对象回收
class->threadLocal 这个强引用断了 就能回收了
线程->map->key----> threadLocal 这个软引用 不会妨碍回收
![](https://img.haomeiwen.com/i4930604/ca6650ca65dcf67d.png)
还是会泄漏的 value
虽然如此还是可能发生内存泄漏,
threadLocal=null
以后
threadLocal 是能被回收了
但是
线程里面那个map的value 还有引用
线程->ThreadLocalMap的那个原来key是那个threadLocal 的 entity ->里面的value
ThreadLocal对象作为ThreadLocalMap的key确实回收了,但是它对应的value没有被回收!
被线程强引用着!
会一直存在到那个线程结束!
如果线程在线程池里面就永远不会结束! 永远回收不了这个没有用的value
避免内存泄漏
不要 用 threadLocal=null
threadLocal.remove()一下
强 | 强引用就不会被回收 |
---|---|
软 | 没引用的对象回收后,还是不够,就回收软引用 |
弱 | 垃圾回收发送就会被回收 |
虚 | gc时通知一下 |
网友评论