专业的JAVA编程教程与资源

网站首页 > java教程 正文

「Java面试」听说你了解多线程开发,说说ThreadLocal吧

temp10 2024-09-04 19:57:46 java教程 30 ℃ 0 评论

ThreadLocal用在什么地方?

ThreadLocal的原理是什么呢?

「Java面试」听说你了解多线程开发,说说ThreadLocal吧

ThreadLocalMap内存储的是什么?

ThreadLocal它是怎样做到线程之间互不干扰的呢?

老版本JDK的ThreadLocal是怎么设计的呢?

JDK8 版本的ThreadLocal设计有什么优势相比更早之前的老版本

ThreadLocalMap 存放数据时,数据的hash值是从Object.hashCode()拿到的,还是其它方式?为什么?

为什么ThreadLocal选择自定义一款Map而没有沿用JDK中的HashMap?

每个线程的 ThreadLocalMap对象 是什么时候创建的呢?

ThreadLocalMap 底层存储数据的数组长度 初始化是多少?

这个数组大小为什么必须为 2的次方数?

ThreadLocalMap的扩容阈值是多少呢?

ThreadLocalMap达到扩容阈值一定会扩容么?

扩容算法 你简单说一说

假设get首次未命中,向下迭代查找时,碰到过期数据了,怎么处理?

探测式清理过期数据,向下迭代过程中碰到正常数据,怎么处理?


什么是ThreadLocal

它是线程内部的本地局部变量,在每个线程里面保存副本,保证多线程之间数据隔离,防止本线程的数据被其他线程改变。它的实例通常是private static类型的,用于关联线程和线程的上下文。

实现原理

在JDK8中 ThreadLocal的设计是:每个Thread维护一个ThreadLocalMap,这个Map的keyThreadLocal实例本身,value才是真正要存储的值Object。

在结构上是不是跟HashMap非常相似,通过Hash运算找到在数组下标中的位置并插入。不同的是,HashMap解决Hash冲突的方式是链表/红黑树,而ThreadLocalMap中用的是开放定址法

ThreadLocal的应用场景

  1. 管理数据库连接的管理:通过ThreadLocal来保证线程里面的数据库连接一定是同一个连接。
  2. 存储线程的事务信息。
  3. Session会话管理。
  4. 日志链路追踪的上下文信息:主要用于保存每次请求的上下文参数,然后在使用的时候通过ThreadLocal来传递,不需要每次都使用参数来传递。
  5. 解决SimpleDateFormat解决线程不安全的问题,不过现在java8提供了DateTimeFormatter它是线程安全的。

ThreadLocal怎么用?

ThreadLocal() 创建ThreadLocal对象

public void set( T value) 设置当前线程绑定的局部变量

public T get() 获取当前线程绑定的局部变量

public void remove() 移除当前线程绑定的局部变量

ThreadLocal如何防止内存泄漏

内存泄漏或脏数据。 我们在使用线程的时候,多数情况都会通过线程池进行管理,这样有些线程在使用完后,并不会进行销毁,

如果我们ThreadLocal也没有执行remove方法,就会导致保存的数据一直存在,造成内存泄漏。如果此时,我们ThreadLocal对象也是一个静态常量,那么在下一次线程被使用的时候,很可能获取到的是之前保存的数据,导致脏数据。

所以,在使用ThreadLocal时,一定要记得在最后调用remove方法。

ThreadLocalMap的key定义成弱引用那么当localThread对象没有强引用指向时,就会被gc回收,避免造成内存泄漏。不过,这里key虽然被回收了,但是value依然会出现内存泄漏问题。只有当线程生命周期结束,或者触发清理算法时,value才能被gc回收。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表