请问一下哈,自定义的ThreadLocal中,为什么不能直接声明一个Map<Thread, T> 来保存value,而是要再套一个map?
秋田君说的也很不错, 我这里补充下, Map<Thread, T>这种结构,hash表冲突会很严重,举个例子。map.put(thread1, 100);map.put(thread1, 200);map.put(thread1, 300);你发现没有,一个map put了三个值,那取值的时候, 怎么办呢?
同样的 main 函数,使用老师的代码执行会发现主线程不同 MyThreadLocal 实例中的数据是互不影响互不干扰的
public static void main(String[] args) {
MyThreadLocal<Long> userIdContext = new MyThreadLocal<>() {
@Override
protected Long initialValue() {
return 1L;
}
};
MyThreadLocal<Connection> connectionContext = new MyThreadLocal<>();
System.out.println(userIdContext.get()); // 1
System.out.println(connectionContext.get()); // null
}从使用上看应该是为了不同场景使用时数据隔离,同一线程之间不同 MyThreadLocal 实例间的数据隔离
@Deprecated
public class MyThreadLocalWrong<T> {
private static Map<Thread, Object> threadLocalMap = new HashMap<>();
protected T initialValue() {
return null;
}
public synchronized T get() {
return (T) threadLocalMap.computeIfAbsent(Thread.currentThread(), t -> initialValue());
}
public synchronized void set(T t) {
threadLocalMap.put(Thread.currentThread(), t);
}
public static void main(String[] args) {
MyThreadLocalWrong<Long> userIdContext = new MyThreadLocalWrong<>() {
@Override
protected Long initialValue() {
return 1L;
}
};
MyThreadLocalWrong<Connection> connectionContext = new MyThreadLocalWrong<>();
System.out.println(userIdContext.get()); // 1
System.out.println(connectionContext.get()); // 1
}
}如果直接使用 Map<Thread, T> 来存储数据,由于 threadLocalMap 是静态变量,那么同一线程不同 MyThreadLocal 实例存储时,数据会被覆盖,读取数据时,会得到错乱的值!
应该为了解耦