ThreadLocal底层原理

1. 简介

在Java中,ThreadLocal是一个非常有用的类,它允许我们在多线程环境中存储和访问线程本地变量

每个线程都可以独立地更改其ThreadLocal实例的值,而不会影响其他线程的值。

2. 线程的分类

线程分为用户线程守护线程

  1. 用户线程就是普通线程
  2. 守护线程就是JVM的后台线程

比如垃圾回收线程就是一个守护线程,守护线程会在其他普通线程都停止运行之后自动关闭。我们可以通过设置thread.setDaemon(true)来把一个线程设置为守护线程。

3. 底层原理

ThreadLocal是Java中所提供的线程本地存储机制,可以利用该机制将数据缓存在某个线程内部,该线程可以在任意时刻、任意方法中获取缓存的数据

3.1 Thread类中有一个ThreadLocalMap类型的变量

ThreadLocal底层是通过ThreadLocalMap来实现的,每个Thread对象(注意不是ThreadLocal对象)中都存在一个ThreadLocalMap。
在这里插入图片描述
Map的key为ThreadLocal对象,Map的value为需要缓存的值。

3.2 ThreadLocalMap是ThreadLocal类的静态内部类

为什么要这样设计呢?

ThreadLocal通过给ThreadLocalMap使用默认的权限修饰符,使得ThreadLocalMap无法被其他包的类引用,最终将ThreadLocalMap完美地隐藏起来,同时ThreadLocal提供了一系列操作容器ThreadLocalMap的方法(get、set等),供外界使用。

3.3 总结

Thread类里面有一个ThreadLocalMap类型的变量,但是外界无法直接操作这个ThreadLocalMap,提供了一个工具箱ThreadLocal帮助我们操作ThreadLocal。

3.4 存在问题

如果在线程池中使用ThreadLocal会造成内存泄漏,因为当ThreadLocal对象使用完之后,应该要把设置的key,value,也就是Entry对象进行回收,但线程池中的线程不会回收,而线程对象是通过强引用指向ThreadLocal对象之后,手动调用ThreadLocal的remove方法,手动清除Entry对象。

3.5 应用场景

ThreadLocal经典的应用场景就是连接管理

一个线程持有一个连接,该连接对象可以在不同的方法之间进行传递,线程之间不共享同一个连接。

4. 使用方法

Thread类里面都包含了一个Map。然后每一个Map就对应了一个ThreadLocal。

然后这样的话,它每次调用一个ThreadLocal的一个类的话,它就会调用ThreadMap里面的具体的那个ThreadLocal。

这样的话,每个线程都对应自己的一个Local的对象,也是一个Object的东西。

4.1 ThreadLocal中的set方法

获取当前线程,然后获取当前线程中的ThreadLocalMap(即threadLocals变量指向的)。

如果不为空,则把当前对象ThreadLocal作为键,外界传过来的参数作为值,保存ThreadLocalMap中。

如果为空,则创建一个新的ThreadLocalMap。

4.2 ThreadLocal中的get方法

先获取当前线程对象,然后拿到当前线程对象的ThreadLocalMap,在根据键(即当前对象ThreadLocal)找到值。

4.3 ThreadLocalMap中键值

ThreadLocalMap以ThreadLocal作为键,值是我们调用ThreadLocal的set方法传进来的。
在这里插入图片描述

4.4 ThreadLocal中的HashMap的键值

在使用ThreadLocal时,我们通常会创建一个静态的ThreadLocal实例,并在需要存储线程本地变量的地方使用它。每个线程都可以它通过ThreadLocal实例来获取和设置线程本地变量的值,而不会影响其他线程。

例如,以下代码片段创建了一个ThreadLocal实例,用于存储线程本地的计数器变量:

private static ThreadLocal<Integer> counter = new ThreadLocal<Integer>(){
	@Override
	protected Integer initialValue(){
		return 0;
	}
};

在每个线程中,可以使用以下代码获取和更新计数器变量的值:

int value = counter.get(); // 获取计数器变量的值
counter.set(value + 1); // 更新计数器变量的值

在这里,ThreadLocal的key是当前线程,value是当前线程本地的计数器变量

5. Thread、ThreadLocal和ThreadLocalMap三者关系

5.1 ThreadLocal的作用

  1. 工具类,提供一系列方法操作ThreadLocalMap,比如get/set/remove。
  2. 隔离Thread和ThreadLocalMap,防止程序员直接创建ThreadLocalMap。自身的get/set内部会判断当前线程是否已经绑定一个ThreadLocalMap,有就继续用,没有就为其绑定。

5.2 Thread和ThreadLocalMap的关系

一个Thread只能有一个ThreadLocalMap。

5.3 ThreadLocalMap和ThreadLocal的关系

ThreadLocalMap以ThreadLocal为键存储数据。

参考资料

  1. 【2分钟搞定八股文面试题】⑦ThreadLocal的底层原理
  2. Thread、ThreadLocal、ThreadLocalMap是什么?看这一篇
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值