> 文章列表 > ThreadLocal 学习常见问题

ThreadLocal 学习常见问题

ThreadLocal 学习常见问题

ThreadLocal 这个此类提供线程局部变量。这些变量不同于通常的对应变量,因为每个访问一个变量的线程(通过 get 或 set 方法)都有自己独立初始化的变量副本。ThreadLocal 实例通常是希望将状态与线程(例如,用户 ID 或事务 ID)关联的类中的私有静态字段。

使用时每个线程复制一个变量副本。每个线程只能使用自己复制的副本,不会用到其他线程的副本。也就不存在多线程贡献问题。

一般应用场景:线程池,数据库连接池,SimpleDateFormat使用

threadLocal 主要通过由ThreadLocalMap来实现,ThreadLocalMap是一个静态内部类。

ThreadLocal 学习常见问题

threadLocal 推导

1.存储功能

。通过数据结构去存储——ThreadLocalMap (Hash表)

Hash表如何理解:就是一个数组,数组的下标是由Hash值运算得来的 ThreadLocalMap和ThreadLocal有什么关联呢

ThreadLocal是UC下面的一个普通的工具类,ThreadLocalMap是ThreadLocaJ里面的一个静态的内

部类

ThreadLocalMap实际上就是我们上面讲的那个Hash表,而这个Hash表里面存的是一个个的Entry节

Entry节点实际上也是一个内部类,对key和value值进行包装

2.在ThreadLocal中如何解决Hash冲突的呢

通过线性探测法去解决hash冲突

3.Hash冲突是怎么产生的

就是通过Key去求Hash值的时候,然后又通过Hash值去计算下标的时候,可能不同的key值算出来相同的下标4.下标又是怎么计算的呢?

key.hashcode=hash值(int类型的数据)int类型是4字节的,32位的数据

4.下标又是怎么计算的呢?

key.hashcode=hash值(int类型的数据)int类型是4字节的,32位的数据

下标的计算:通过hash值&(数组长度-1)16-1 =158-1=7 10-1 =91001

11010111 11010111 11010111 11010111

1001

=1001

为什么通过hash值&(数组长度-1)通过这样计算?

这样计算减少hash碰撞

强:引用指向new关键字创建的对象,则该引用就叫强引用,即使内存满足,要溢出了,也不会回收强引用指向的对象

软:软引用在内存充足的时候不会被回收,当内存不足的时候会被回收

弱:不管内存充不充足,只要垃圾回收,就会被回收掉

6. ThreadLocalMap中的key为什么要用弱引用呢?

采用弱引用能减少内存泄漏,因为复制的副本中的key存放在ThreadLocalMap中,如果用强引用线程副本的应用就不会断开即使,外部变量复制为空,也不能进行内存回收,导致内存泄漏。

为什么不是解决内存泄漏。因为value是强引用。

entry中key是弱引用,value是强引用

ThreadLocal 学习常见问题

7.为什么不吧value值也设计成弱引用呢?

value设置成弱引用,当key没有被回收时,通过get获取时value可能为空值

8.那怎么解决内存泄漏呢?

通过手动调用remove方法就能解决内存泄漏