美文网首页
理解ThreadLocal

理解ThreadLocal

作者: 躁动的中年大叔 | 来源:发表于2019-01-06 18:32 被阅读11次

    ThreadLocal其实可以理解为一个工具类,用来操作线程局部变量
    ThreadLocal为每一个使用该变量的线程都提供一个变量值的副本,使得每一个线程都可以修改自己的变量值副本,而不影响其他线程的变量值。

    一、ThreadLocal的使用

    1. 创建ThreadLocal实例

    1.1 直接创建(指定类型参数)

    ThreadLocal tl = new ThreadLocal<Integer>();
    

    1.2 指定初始值的方式创建

    // 指定初始值为 1,若不指定则为null
    ThreadLocal tl = new ThreadLocal<Integer>(){
        @Override
        protected Integer initialValue(){
            return 1;
        }
    };
    

    2. 给ThreadLocal实例赋值

    // 当前线程的该局部变量的值设为10
    tl.set(10);
    

    3. 获取ThreadLocal实例的值

    Integer value = tl.get();
    

    二、ThreadLocal的原理

    刚接触到ThreadLocal的概念时,可能大多数人都误以为线程的变量值副本都存储在ThreadLocal实例中一个Map结构中,key为线程的标识,value为线程对应的变量值副本。

    其实不是这样的,在Thread类里有个threadLocals 的属性,是一个ThreadLocalMap 结构,它将每一个ThreadLocal实例作为key,value为该线程的变量值副本。

    即线程的各个局部变量值是存储在线程实例本身中的,ThreadLocal只是获取对应线程局部变量值的标识,也就可以理解为一个工具类了。

        /* ThreadLocal values pertaining to this thread. This map is maintained
         * by the ThreadLocal class. */
        ThreadLocal.ThreadLocalMap threadLocals = null;
    

    值得注意的是,ThreadLocalMap 的每一个Entry都是ThreadLocal的一个弱引用(基于JDK1.8),当对应的ThreadLocal实例在失去了强引用,只剩下Entry这个弱引用后将被GC回收,对应的Entry也就为null了,是不存在内存泄漏问题的。

    三、ThreadLocal的缺点

    其实不应该叫缺点,应该叫使用时需要注意的地方更合适。
    我们都知道,线程的创建和销毁都是要付出代价的,日常使用多线程时,包括Tomcat服务器,都是通过线程复用的方式使用多线程,即会使用到线程池。

    这种情况下不同的事务请求可能就会复用同一个线程,所以每次使用时要注意为ThreadLocal重新赋值以及使用完成后做相应的清理,否则就会出现意想不到的结果。

    相关文章

      网友评论

          本文标题:理解ThreadLocal

          本文链接:https://www.haomeiwen.com/subject/jhzdrqtx.html