面试必问之 – ThreadLocal
内容提要
ThreadLocal是一个线程内部的数据存储类,能够在指定的线程中存储数据,每个线程的数据都是独立的。ThreadLocal的set()方法先获取当前线程的ThreadLocalMap目标,然后将数据存入Map中。ThreadLocalMap是ThreadLocal内部的一个静态类,它是一个弱引证目标,用于存储数据。ThreadLocal的get()方法先获取当前线程的ThreadLocalMap目标,然后从Map中获取数据,如果Map为空,则将初始值存入Map中。ThreadLocal的存储和获取数据的操作都依赖于ThreadLocalMap目标。
延伸解读
为什么线程间数据互不干扰
ThreadLocal 的数据独立性源于每个线程都持有自己的 ThreadLocalMap 对象。当调用 set 或 get 时,会先通过 Thread.currentThread() 获取当前线程,再取得该线程绑定的 ThreadLocalMap,因此不同线程操作的是不同的 Map,自然互不影响。
弱引用 Entry 的设计与内存回收
ThreadLocalMap 的 Entry 继承自 WeakReference,其 key 是弱引用的 ThreadLocal 对象。当 ThreadLocal 实例不再被强引用时,Entry 的 key 会在内存不足时被自动回收,但 value 仍被 Entry 强引用,可能造成内存泄漏,需注意及时调用 remove。
set 与 get 的底层流程
set 方法先获取当前线程的 ThreadLocalMap,若不存在则创建并存入初始值,否则直接更新或插入 Entry。get 方法同样先获取 Map,若 Map 或 Entry 为空,则调用 setInitialValue 存入初始值并返回。整个过程依赖 ThreadLocalMap 的哈希定位与冲突处理。
Q&A
什么是ThreadLocal?
ThreadLocal是一个线程内部的数据存储类,能够在指定的线程中存储独立的数据。
ThreadLocal的set()方法是如何工作的?
set()方法通过获取当前线程的ThreadLocalMap目标,将数据存入Map中,如果没有Map则创建一个新的。
ThreadLocal如何确保线程间数据的独立性?
ThreadLocal通过为每个线程创建独立的ThreadLocalMap,确保每个线程的数据互不干扰。
ThreadLocalMap是什么?
ThreadLocalMap是ThreadLocal内部的一个静态类,用于存储数据,并且是一个弱引用目标。
ThreadLocal的get()方法是如何获取数据的?
get()方法通过获取当前线程的ThreadLocalMap目标,从中获取数据,如果Map为空则初始化值。
ThreadLocalMap中的Entry类有什么作用?
Entry类用于存储数据,并在内存不足时自动回收,它是ThreadLocalMap内部的一个静态类,继承自WeakReference。