ThreadLocal用在什么地方?
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的key是ThreadLocal实例本身,value才是真正要存储的值Object。
在结构上是不是跟HashMap非常相似,通过Hash运算找到在数组下标中的位置并插入。不同的是,HashMap解决Hash冲突的方式是链表/红黑树,而ThreadLocalMap中用的是开放定址法。
ThreadLocal的应用场景
- 管理数据库连接的管理:通过ThreadLocal来保证线程里面的数据库连接一定是同一个连接。
- 存储线程的事务信息。
- Session会话管理。
- 日志链路追踪的上下文信息:主要用于保存每次请求的上下文参数,然后在使用的时候通过ThreadLocal来传递,不需要每次都使用参数来传递。
- 解决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回收。
本文暂时没有评论,来添加一个吧(●'◡'●)