请问为什么不能直接使用一个Thread和Value绑定的Map?

来源:4-1 实现自己的ThreadLocal

全菜工程__

2020-02-10 16:03

请问一下哈,自定义的ThreadLocal中,为什么不能直接声明一个Map<Thread, T> 来保存value,而是要再套一个map?

写回答 关注

4回答

  • 求老仙
    2020-02-21 02:00:01

    秋田君说的也很不错, 我这里补充下, Map<Thread, T>这种结构,hash表冲突会很严重,举个例子。map.put(thread1, 100);map.put(thread1, 200);map.put(thread1, 300);你发现没有,一个map put了三个值,那取值的时候, 怎么办呢?

  • 秋田君
    2020-02-17 13:19:47

    同样的 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
    }


  • 秋田君
    2020-02-17 13:13:52

    从使用上看应该是为了不同场景使用时数据隔离,同一线程之间不同 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 实例存储时,数据会被覆盖,读取数据时,会得到错乱的值!

  • 隐身就是现在
    2020-02-10 17:58:35

    应该为了解耦

ThreadLocal

设计者视角源码级ThreadLocal分析教你建立线程安全感-你专属的技术优越感

14065 学习 · 32 问题

查看课程

相似问题