本文主要是介绍大白话之ThreadLocal,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
ThreadLocal是什么?
一般情况下,我们创建的变量可以被任何线程访问并且修改。如果线程需要有自己的一个本地变量怎么办?
ThreadLocal就是做这个事情的,它允许你创建的变量值对于使用该变量的每个线程来说都是独立的。可以将ThreadLocal类形象的比喻成存放数据的盒子,盒子中可以存储每个线程的私有数据。
ThreadLocal原理了解麻?
Thread类内部维护了一个ThreadLocalMap,可以说是ThreadLocal实现的一个定制化hashMap,它以ThreadLocal为key,以ThreadLocal储存的值为value,当我们的当前线程中的ThreadLocal调用set()或者get()方法时,会先判断当前的ThreadLocalMap是否存在,因为默认是null,如果不存在,就创建一个新的ThreadLocalMap并将其与当前线程关联。实际上set与get方法的调用其实是调用的ThreadLocalMap的set与get方法。
我们最终的变量其实放在了ThreadLocalMap中,并不是存在ThreadLocal中!
每个Thread中都具备一个ThreadLocalMap,而ThreadLocalMap可以存储以ThreadLocal为 key ,Object 对象为 value 的键值对。
ThreadLocal内存泄漏问题是怎么导致的?
如果我们的使用的是线程池中的线程,那么当任务完成时,线程并不会销毁,依然存活,那么我们的ThreadLocalMap也就不会被GC回收,也就造成了内存泄漏,更严重的时下一次该线程如果在次存入新的ThreadLocal,依然不会被回收,如此以往就会造成OOM!
当然即使不使用线程池也会造成内存泄漏问题,主要是因为ThreadLocalMap中的key是弱引用,而value属于强引用,当我们的GC进行垃圾清楚时,会将弱引用的key回收,但是不会回收value,只要我们的Thread还存活,那我们的ThreadLocalMap也会一直存活,即使key值被回收,但是value仍然会存活,这就会造成对象的不可达,出现内存泄漏的问题。
解决这个问题通常需要手动调用 ThreadLocal 的 remove() 方法,这样可以清除当前线程 ThreadLocalMap 中对应的条目。
总结:
1. ThreadLocal是Java中所提供的线程本地存储机制,可以利用该机制将数据缓存在某个线程内部,该线程可以在任意时刻、任意方法中获取缓存的数据
2. ThreadLocal底层是通过ThreadLocalMap来实现的,每个Thread对象(注意不是ThreadLocaI对象)中都存在一个ThreadLocalMap, Map的key为ThreadLocal对象, Map的value为需要缓存的值
3.Threadl ocal经典的应用场景就是连接管理(一个线程持有一一个连接, 该连接对象可以在不同的方法之间进行传递,线程之间不共享同一一个连接)
这篇关于大白话之ThreadLocal的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!