线程级别的变量隔离:为每个线程创建独立的变量副本,实现线程封闭(Thread Confinement)
维度 | synchronized | ThreadLocal |
---|---|---|
数据可见性 | 线程间共享 | 线程私有 |
资源竞争 | 存在锁竞争 | 无竞争 |
内存消耗 | 低(共享资源) | 高(每个线程独立副本) |
适用场景 | 数据需要跨线程共享 | 数据需要线程隔离 |
// Thread类内部存储
ThreadLocal.ThreadLocalMap threadLocals;
// ThreadLocalMap内部Entry数组
static class Entry extends WeakReference<ThreadLocal<?>> {
Object value;
}
public class UserContextHolder {
// 使用静态变量防止多次创建
private static final ThreadLocal<User> context = new ThreadLocal<>();
public static void setUser(User user) {
context.set(user);
}
public static User getUser() {
return context.get();
}
// 必须清理防止内存泄漏
public static void clear() {
context.remove();
}
}
// 使用示例
public class AuthFilter {
void doFilter() {
User user = loadUser();
UserContextHolder.setUser(user);
try {
// 业务处理...
} finally {
UserContextHolder.clear();
}
}
}
泄漏根源:
解决方案:
remove()
ThreadLocal<String> parent = new InheritableThreadLocal<>();
parent.set("main");
new Thread(() -> {
System.out.println(parent.get()); // 输出"main"
}).start();
注意事项:
ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd"));
内存泄漏检测:
// 获取当前线程的ThreadLocalMap
Field threadLocals = Thread.class.getDeclaredField("threadLocals");
threadLocals.setAccessible(true);
Object map = threadLocals.get(Thread.currentThread());
// 反射检查Entry数量
Field tableField = map.getClass().getDeclaredField("table");
tableField.setAccessible(true);
Object[] entries = (Object[]) tableField.get(map);
// RequestContextHolder实现原理
public abstract class RequestContextHolder {
private static final ThreadLocal<RequestAttributes> requestAttributesHolder =
new NamedThreadLocal<>("Request attributes");
}
// 全链路追踪实现
public class TraceContext {
private static final ThreadLocal<String> traceId = new ThreadLocal<>();
public static void start() {
traceId.set(UUID.randomUUID().toString());
}
public static String getTraceId() {
return traceId.get();
}
}
方案 | 优点 | 缺点 |
---|---|---|
ThreadLocal | 简单高效 | 内存泄漏风险 |
ScopedValue(Java 20) | 结构化绑定 | 需要新版本支持 |
ConcurrentHashMap | 支持并发访问 | 需要处理线程竞争 |
特别要注意内存泄漏的预防,建议结合代码审查工具(如FindBugs)和内存分析工具(MAT)进行定期检查。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。