ThreadLocal原理和相关问题

ThreadLocal学习

面试题总结

1、TreadLocal到底是干什么的?

ThreadLocal是为了做线程隔离的,就是线程之间互不干扰,它是一个数据结构,有点像HashMap,可以保存"key : value"键值对,但是一个ThreadLocal只能保存一个,并且各个线程的数据互不干扰。

线程可以理解为人,那么张三和李四要动用同一个钱包(不同线程处理相同的变量),可以将钱包(变量)复制一份,具体的例子如下:

比如多个线程执行 int num = 0 ;num += 5;使用ThreadLocal之后,每个线程之间操作的num就不会互相影响,每一个线程拿到的num=5, 没有ThreadLocal的话,有些线程就会在其他线程的基础上加上5,最终拿到的就有可能是5,10, 15, 20…

2、ThreadLocal的底层数据结构是什么?

就是一个Hash表

Hash表就是,因为我们的数组下标是通过hash值计算而来的,所以,当前这个数组叫做Hash表

3、ThreadLocal的底层中Hash数组的默认长度是多少?

16

4、ThreadLocal当容量达到多少时,会触发扩容?

扩容因子: 2/3 ,注意(HashMap的扩容因子是0.75)

为什么是2/3,如果太小的话,就会造成数组的频繁扩容,如果太大的话,就会浪费数组的内存空间

5、hashcode是一个int类型的数据,这个int类型的数据长度是32位?

00000000 00000000 00000000 00000000

怎么计算hashcode , 取模

6、ThreadLocal如何处理hash冲突的呢?

线性探测法

7、ThreadLocal的hashcode是通过一个魔数来计算的,通过斐波那契额散列求出来的

魔数= 黄金分割比(0.618) * 2 ^ 32

8、ThreadLocal的Map数组的长度为什么一定要确保是2的幂次方呢?

为了减少hash冲突

int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY - 1);

上面这个代码就是为了计算数组的下标(通过hashcode 于数组长度减一相与)

32为的hashcode中低4位表示数组的下标

比如一个hashcode如下:

01010011 10000100 01011001 100000100 (2的次幂形式都是1,比如1111)

相与的话

01010011 10000100 01011001 10000**0100**

& 1111


​ 0100 这样子最后四位就不会变

但如果不是2的次幂这种1111的形式的话,最后得到后四位相与的结果就会发生变化:

01010011 10000100 01011001 100000100 (2的次幂形式都是1,比如1111)

相与的话

01010011 10000100 01011001 10000**0100**

& 1011


0000 会发现原本hashcode的后四位是0100,现在结果变为了 0000

9、java中有几种引用类型?

强引用:Object obj = new Object(); 当对象被强引用关联的时候,不管你内存充不充足,垃圾回收的时候都不会回收

软引用:当垃圾回收的时候,如果内存充足,则不会回收该对象,如果内存不足了,则会回收

弱引用:当垃圾回收的时候,不管内存充不充足,都会回收

虚引用:

10、ThreadLocal中的Key值使用的是弱引用,为什么要使用弱引用?

为了减少内存泄漏问题,如果是强引用的话,不会回收内存,内存被回收不了,就会造成内存泄漏

11、Key使用了弱引用,为什么还会出现内存泄漏的问题呢?

因为Map中的value依然使用的是强引用,回收不了,会造成内存泄漏

那为什么value不像key一样使用弱引用?

value不值设置为弱引用,否则假如value被回收了,key还在的话,会出现map.get(key) =null

12、如何彻底解决内存泄漏问题?

解决办法是每次使用完ThreadLocal都调用它的remove()方法清除数据,或者按照JDK建议将ThreadLocal变量定义成private static,这样就一直存在ThreadLocal的强引用,也就能保证任何时候都能通过ThreadLocal的弱引用访问到Entry的value值,进而清除掉。

13、ThreadLocal怎么使用呢?

1、创建对象 ThreadLocal girl = new ThreadLocal():

2、girl.set();

3、girl.get();

replaceStaleEntry

1、清理一下无效的节点(Entry(null, 2)), Entry中的key为null的这一类

2、进行线性探测,存数据

14、ThreadLocal的set和get方法

set
在这里插入图片描述

get

在这里插入图片描述

15、ThreadLocal和Synchonized

两者都用于解决多线程并发访问。但是ThreadLocal与synchronized有本质的区别。Synchronized用于线程间的数据共享,而ThreadLocal则用于线程间的数据隔离。Synchronized是利用锁的机制,使变量或代码块在某一时该只能被一个线程访问。而ThreadLocal为每一个线程都提供了变量的副本,使得每个线程在某一时间访问到的并不是同一个对象,这样就隔离了多个线程对数据的数据共享。而Synchronized却正好相反,它用于在多个线程间通信时能够获得数据共享。

16、ThreadLocal中的key和value

dLocal为每一个线程都提供了变量的副本,使得每个线程在某一时间访问到的并不是同一个对象,这样就隔离了多个线程对数据的数据共享。而Synchronized却正好相反,它用于在多个线程间通信时能够获得数据共享。

2022-07-02

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值