ThreadLocal怎么说
ThreadLocal怎么说
这么说
- ThreadLocal可以实现资源的线程隔离,避免线程安全问题
- ThreadLocal实现了线程内的资源共享
- 其原理是,每个线程内有一个ThreadLocalMap类型的成员变量,用来存储资源
1)调用set方法就是以ThreadLocal自己作为key,资源作为value,放入当前线程的ThreadLocalMap集合中
2)调用get方法就是以ThreadLocal自己作为key,到当前线程中查找关联的资源
3)调用remove方法就是以ThreadLocal自己作为key,移除当前线程关联的资源 - 为什么ThreadLocalMap中的key(即ThreadLocal)要设计为弱引用?
1)线程可能会长时间运行(如线程池中的线程),如果key不再使用,需要在内存不足(GC)时释放其占用的内存
2)但是GC只是释放key的内存,后续还得根据key是否为null来进一步释放值的内存,时机有:a)get key时,发现为null b)set key时,会使用启发式扫描,清除临近的为null的key, 启发次数与元素个数、是否发现为null的key有关 c)remove时(推荐),因为一般使用ThreadLocal时都把它作为 静态变量,因此GC无法回收,推荐remove掉
- 内存泄漏
https://zhuanlan.zhihu.com/p/58636499
https://www.cnblogs.com/arielmeng/p/15617405.html
https://juejin.cn/post/6844903985745231885
上文总结一下:
弱引用:
ThreadLocal自身并不储存值,而是作为一个key来让线程从ThreadLocalMap获取value。Entry是中的key是弱引用,所以jvm在垃圾回收时如果外部没有强引用来引用它,ThreadLocal必然会被回收。但是,作为ThreadLocalMap的key,ThreadLocal被回收后,ThreadLocalMap就会存在null,但value不为null的Entry。若当前线程一直不结束,可能是作为线程池中的一员,线程结束后不被销毁,又不再调用对应的get/set方法,那这个value就会一直存在,无法回收,就引发内存泄漏。
强引用:略