栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

ThreadLocal原理和相关问题

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1003505.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号