面试必问之 – ThreadLocal

💡 原文中文,约6100字,阅读约需15分钟。
📝

内容提要

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。

🏷️

标签

➡️

继续阅读