全菜工程__
2020-02-10 16:03
请问一下哈,自定义的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 实例存储时,数据会被覆盖,读取数据时,会得到错乱的值!
应该为了解耦
ThreadLocal
14065 学习 · 32 问题
相似问题