ThreadLocal的用途
1、保存线程的上下文信息,在任意需要的地方可以获取,但不被多线程共享
由ThreadLocal的特性可知,在同个线程里面,针对同个ThreadLocal对象的赋值,在线程中都是可以根据该ThreadLocal对象获取的,而ThreadLocal同时也是线程私有的,不用担心共享数据的问题。
对服务器端来说,每次请求都是一条线程处理,可以把请求的数据放在ThreadLocal中,从controller --> service --> dao层,甚至RPC调用,都不用修改方法参数或类变量,直接通过ThreadLocal设置或获取即可
2、线程安全的,避免某些需要考虑线程安全必须同步带来的性能损失
ThreadLocal其实无法处理共享数据的多线程并发问题的,它最多只是把共享数据在自己的线程内部拷贝了一个副本而已,针对共享数据的写操作还是会有并发问题的,线程的共享数据的拷贝也无法知道共享数据的最新的值
ThreadLocal结构图
踩坑:
之前认为ThreadLocalMap是所有线程公用这个集合的,后来发现是每个线程都维护了一个map集合,即threadLocals字段,key为不同的ThreadLocal对象
源码部分
1、常用方法介绍
2、hash冲突解决
与 HashMap 不同,ThreadLocalMap 结构非常简单,没有 next 引用,也就是说 ThreadLocalMap 中解决 Hash 冲突的方式并非链表的方式,而是采用线性探测的方式。所谓线性探测,就是根据初始 key 的 hashcode 值确定元素在 table 数组中的位置,如果发现这个位置上已经被其他的 key 值占用,则利用固定的算法寻找一定步长的下个位置,依次判断,直至找到能够存放的位置。
关于0x61c88647这个数字是如何让哈希码能均匀的分布在2的N次方的数组里,详情可看:https://zhuanlan.zhihu.com/p/40515974