什么是 ThreadLocal?

ThreadLocal 是 Java 提供的一种用于线程本地存储的工具类,它可以为每个线程提供独立的变量副本,从而实现线程隔离。ThreadLocal 主要用于在多线程环境下存储线程独有的数据,避免多个线程间共享变量带来的数据一致性问题。
1.应用场景
| 应用场景 | 说明 |
|---|---|
| 数据库连接管理 | 绑定 Connection到线程,避免同步问题 |
| 用户身份管理 | 线程隔离 Session,存储用户信息 |
| 日志追踪 | 存储 Trace ID,方便日志分析 |
| 日期格式化 | 避免 SimpleDateFormat线程不安全问题 |
| 线程计数器 | 统计当前线程的执行次数 |
| 线程池数据传递 | 使用 TransmittableThreadLocal解决线程池数据丢失问题 |
2.如何使用
- 创建 ThreadLocal
创建了一个 ThreadLocal 变量 localVariable,任何一个线程都能并发访问 localVariable。
public static ThreadLocal<String> localVariable = new ThreadLocal<>();
- 新增数据,线程可以在任何地方写入数据
localVariable.set("测试数据");
- 读取数据,线程在任何地方都能够读取数据
localVariable.get();
- 删除数据,
localVariable.remove();
底层原理
1.数据存储
ThreadLocal 变量的值存储在 Thread 内部的 ThreadLocalMap ,不是 ThreadLocal 本身。
public class ThreadLocal<T> {
static class ThreadLocalMap {
static class Entry extends WeakReference<ThreadLocal<?>> {
// 弱引用类型
Object value; // 强引用
Entry(ThreadLocal<?> k, Object v) {
super(k); // ThreadLocal 类型作为key,弱引用
value = v;
}
}
private Entry[] table;
}
}
ThreadLocalMap采用 线性探测法 解决哈希冲突- 弱引用:
Entry继承WeakReference,ThreadLocal对象被回收时,键会变为null,避免内存泄漏 - 每个
Thread维护一个ThreadLocalMap实例,键是ThreadLocal,值是变量
1.1Thread 、ThreadLocal、ThreadLocalMap、Entry 之间的关系
[Thread]
|
v
[ThreadLocalMap] (threadLocals)
|
v
[Entry[]] (table)
|
+--> [Entry1] --> key: WeakReference<ThreadLocalA>
| value: ValueA
|
+--> [Entry2] --> key: WeakReference<ThreadLocalB>
value: ValueB
Thread 线程可以拥有多个 ThreadLocal 维护的自己线程独享的共享变量(这个共享变量只是针对自己线程里面共享)
2.set()
public void set(T value) {
Thread t = Thread.currentThread(); // 获取当前线程
ThreadLocalMap map = getMap(t); // 获取线程的ThreadLocalMap
if (map != null) {
map.set(this, value);
} else {
createMap(t, value);
}
}
- 先获取当前线程
ThreadLocalMap - 如果
map存在,直接存入ThreadLocalMap - 否则创建一个新的
ThreadLocalMap
3.get()
public T get() {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);
if

最低0.47元/天 解锁文章
1万+

被折叠的 条评论
为什么被折叠?



