ThreadLocal 没有“线程安全”一说,正确来讲 ThreadLocal 实现是不存在线程/资源竞争的。 ThreadLocal 通常用作业务上下文,事务传递管理等场景中。本文将从源码着手分析 ThreadLocal 相关特性。
示例代码
下方为创建 ThreadLocal 的方式,一般 ThreadLocal 会被修饰为静态常量。
ThreadLocal<Object> local = new ThreadLocal<>();
local.get();
local.set(new Object());
ThreadLocal 并不存储数据,ThreadLocal 仅负责操作当前线程下数据。每条 Thread 中都存在 ThreadLocal.ThreadLocalMap threadLocals;
threadLocals
并不是创建线程时创建的,而是在操作ThreadLocal
实例时创建的(见下方 set 方法)
ThreadLocalMap 对象
ThreadLocalMap 对象主要操作类似 HashMap 其 KEY 为当前 ThreadLocal<T> Value 为 T。
需要注意的是元素 Entry
对象是一个 WeakReference 对象,可能随时被虚拟机回收。
set 方法
public void set(T value) {
// 获取当前线程
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}
为什么说ThreadLocal内存泄漏
需要注意
- 当业务逻辑完成应将对调用 ThreadLocal 的 remove 方法,防止内存泄漏和业务冲突。
网友评论