看ThreadLocal源码引发的思考

/ 笔记 / 无站内评论 / 586浏览


刚开始看网上不少ThreadLocal博文,对ThreadLocal初步认识之后,不免产生一些疑问,可是学习中的一些难点吧,然后跟同事再次看源码讨论一番之后,深刻理解的该ThreadLocal类。下面总结一下。


首先引用同事总结的内容:



    

引用张苗博客下文:


ThreadLocal类


线程局部变量(ThreadLocal)为每一个使用该变量的线程都提供一个变量值的副本,使每一个线程都可以独立地改变自己的副本,而不会和其他线程的副本冲突。


ThreadLocal类方法 :


T get() : 取得当前线程副本数据值


void remove() :删除当前线程副本数据值


void set(T value) :设置当前线程副本数据的值


T initialValue() 创建时对其初始化


ThreadLocal类是从另一个角度来解决多线程的并发访问,ThreadLocal将需要并发访问的资源复制多份,每个线程拥有一份资源,每个线程都拥有自己的资源副本,从而也就没有必要对该变量进行同步了。






1.ThreadLocal的变量副本存在哪?一个线程多个ThreadLocal定义又存哪?


类中定义ThreadLocal,分别存储了用户和Sesion对象



首先我们看下ThreadLocal源码中的get方法。





首先获取当前线程,然后获取当前线程中的ThreadLocalMap.



然后我们再进去看t.threadLocals的源码


我们发现ThreadLocalMap是Thread线程的成员变量!



然后我们再回来看下ThreadLocalMap的set方法



没错,还是首先获取当前线程中的ThreadLocalMap变量,如果存在map,就进入往里面放参数,如果不存在,就新建一个map。



创建的map也是对Thread线程创建。


ThreadLocalMap存储的key为ThreadLocal对象,value为定义时泛型。



如刚开始定义的,USER这个实例对象就是当作key放入线程的map,然后value就是要保存的SysUser。




然后回顾开头的问题。


ThreadLocal的变量副本存在哪?一个线程多个ThreadLocal定义又存哪?


我们之前理解线程时有点错误,以为ThreadLocal就是一个线程。那问题来了,如果类中定义两个ThreadLocal呢?那岂不是存在两个线程了,所以肯定是错误的。所以认真看了下源码,发现。


当前线程是从一次请求开始到结束。定义的ThreadLocal可以说是线程局部变量,ThreadLocal存储的值放在Thread线程中,就是线程中的ThreadLocalMap。 map中的key就是每个ThreadLocal对象(USER),值就是ThreadLocal对象set存放的对象(SysUser)。


ThreadLocalMap存储当前线程中所有定义的ThreadLocal。


召唤蕾姆
琼ICP备18000156号

鄂公网安备 42011502000211号