首页 > 其他分享 >详细了解ThreadLocal底层原理及作用

详细了解ThreadLocal底层原理及作用

时间:2024-08-30 18:51:57浏览次数:9  
标签:set 变量 ThreadLocalMap ThreadLocal threadLocal 线程 原理 底层

深入ThreadLocal底层原理

一、ThreadLocal的作用

ThreadLocal是Java中一个用于实现线程局部变量的类。它的主要作用是在每个线程中创建一个变量的副本,这样每个线程可以独立地访问自己的副本,而不必担心其他线程的影响。这对于解决多线程环境下的线程安全问题非常有用,可以避免使用锁所带来的复杂性和性能损耗。

二、ThreadLocal的底层原理

在这里插入图片描述
从内存图中分析,我们可以看出:

每一个Thead类中都有一个成员变量 ThreadLocalMap,它内部维护着一个Entry对象数组,每一个Entry对象里面都有一对键值对,其中键是创建的ThreadLocal变量,值是每个线程设置的变量副本,而且数组里面每个Entry对象的键都是同一个ThreadLocal变量,而值是不同的。

ThreadLocal使用实例

public class ThreadLocalExample {

    // 创建一个ThreadLocal实例
    public static final ThreadLocal<String> threadLocal = new ThreadLocal<>();

    public static void main(String[] args) {
        // 在主线程中设置值
        threadLocal.set("主线程的值");

        // 在主线程中获取值
        System.out.println("主线程的值:" + threadLocal.get());

        // 创建一个新的线程,并在其中设置和获取值
        Thread thread = new Thread(() -> {
            threadLocal.set("子线程的值");
            System.out.println("子线程的值:" + threadLocal.get());
        });

        thread.start();
    }
}

涉及到的源码如图所示:

  1. get()获取线程局部变量值

在这里插入图片描述
2. set()设置线程局部变量值
在这里插入图片描述
3. 获取当前线程内部的ThreadLocalMap变量
ThreadLocal成员方法
4. Thread类中的ThreadLcalMap变量
在这里插入图片描述
5. 创建一个ThreadLcalMap对象变量
在这里插入图片描述

代码分析:

  • 调用set():在通过创建的TreadLocal类threadLocal 变量调用set方法时候,源码里首先是获取了当前线程,然后再通过getMap方法返回当前线程内部的ThreadLocalMap变量,由于初始化为null故而会先创建一个ThreadLocalMap对象并将当前threadLocal作为键,set中的参数作为值赋值给entry对象,此时创建了一个线程的变量副本。
  • 调用get():在通过创建的TreadLocal类threadLocal 变量调用get方法时候,源码里首先是获取了当前线程,然后再通过getMap方法返回当前程内部的ThreadLocalMap变量,并通过threadLocal 变量获取当前线程的值。

三、可能存在的问题

  1. 最典型的问题就是内存泄漏
  • 生命周期管理不当:ThreadLocal的set方法在每个线程中存储一个值,但如果线程长时间运行并且未调用remove方法显式清除不再需要的ThreadLocal变量,那么这些变量将一直存在于线程的ThreadLocalMap中,可能导致内存泄漏。

  • 弱引用问题:ThreadLocalMap中的Entry使用弱引用来引用ThreadLocal对象。如果ThreadLocal对象没有外部强引用,那么ThreadLocal对象将被垃圾回收,而其对应的Entry则成为孤立的条目,导致内存泄漏。

解决方法

及时清理。显式调用remove方法:在不再需要ThreadLocal变量时,显式调用remove方法来清理该变量。这有助于防止内存泄漏。

  1. 生命周期结束时未清理

线程池场景:在使用线程池的情况下,线程可能会被重复使用。如果线程在完成一个任务后没有及时清理ThreadLocal变量,那么这些变量可能会被后续的任务使用,导致数据混淆或错误行为。

解决方法

在合适的地方清理:在使用线程池的情况下,可以在线程任务完成后清理ThreadLocal变量。例如,在Runnable或Callable任务结束时调用ThreadLocal的remove方法。

四、总结

ThreadLocal提供了一种简单而强大的机制来解决线程安全问题,尤其是在需要每个线程都有独立变量副本的场景下。通过合理地使用ThreadLocal,可以大大简化多线程编程的复杂度,并提高代码的可读性和可维护性,同时在不再需要ThreadLocal变量时,显式调用remove方法来清理该变量,防止内存泄漏。

标签:set,变量,ThreadLocalMap,ThreadLocal,threadLocal,线程,原理,底层
From: https://blog.csdn.net/a147775/article/details/141723123

相关文章

  • 第一篇:爬虫基本原理
    爬虫是什么 1、什么是互联网?互联网是由网络设备(网线,路由器,交换机,防火墙等等)和一台台计算机连接而成,像一张网一样。2、互联网建立的目的?互联网的核心价值在于数据的共享/传递:数据是存放于一台台计算机上的,而将计算机互联到一起的目的就是为了能够方便彼此之间的......
  • MySQL索引底层结构为什么用B+Tree?
    索引为何不选择二叉树?二叉搜索树是遵守二分搜索法实现的一种数据结构,它具有下面特点:任意节点的左节点不为空时,左节点值小于根节点值;右节点不为空时,右节点值大于根节点值;依次存入数据,如果数据是递增的,则原二叉树退化为链表结构 从动画中可以明显看到,需要经过5次查询才能......
  • PG复制槽的原理
    什么是PG复制槽?PG复制槽用于记录主备流复制的状态,主要目的是防止wal日志被过早的删除,导致备库流复制中断。复制槽是有状态的,能够持久化到磁盘上,允许宕机、重启场景下进行恢复。在有复制槽的场景下,即使备库关闭很长时间,主库也会为其保留足够的wal日志,直到备库恢复接收完这......
  • SpringBoot原理
    目录一、配置优先级二、Bean管理1.获取Bean(1)三种方式(2)获取示例 2.Bean作用域 3.第三方Bean 三、SpringBoot原理1.起步依赖2.自动配置(1)概述(2)准备工作 (3)@Import (4)模拟过程3.自动配置原理(1)源码跟踪 (2)@Conditional (3)自定义start业务场景需求 步骤具......
  • Java人证合一接口原理、身份证识别、人工智能
    人脸识别,是基于人的脸部特征信息进行身份识别的一种生物识别技术。用摄像机或摄像头采集含有人脸的图像或视频流,并自动在图像中检测和跟踪人脸,进而对检测到的人脸进行脸部的一系列相关技术,通常也叫做人像识别、面部识别。人证合一接口,一般是指人脸与身份证识别接口的相结......
  • pinpoint-php-aop 内部原理
    pinpoint-php-aop是一个支持pinpoint-phpagent的库自动注入PHP内置函数,比如redis,pdo,mysqli自动注入用户类,比如guzzlehttp,predis怎样处理内置函数内置函数解释:PHPcomesstandardwithmanyfunctionsandconstructs.Therearealsofunctionsthatrequir......
  • @Import注解 -【Spring底层原理】
    通过在配置类上使用@Import注解,将User给注入进容器中,运行启动类,可以看到容器中有User对象:image-20210226164625069【2】导入ImportSelector的实现类导入ImportSelector的实现类需要实现ImportSelector类,自定义逻辑返回需要导入的组件,返回的字符串数组即是要注入的组件,添加修改......
  • 【JVM原理】类加载机制
    文章目录一、JVM组成二、类的生命周期2-1加载(Loading)2-2连接(Linking)2-3初始化(Initialization)2-4使用(Using)2-5卸载(Unloading)三、类加载器3-1类加载器的作用3-2类加载器的种类3-3类加载机制双亲委派机制(ParentDelegationModel)全盘负责委托机制(Fu......
  • BMS中预充工作原理
    在电池管理系统(BMS)中,预充是指在充电过程中,特别是在电池电压较低或电池处于休眠状态时,先进行小电流充电的过程。其工作原理和目的主要包括以下几个方面:1. 目的激活电池:对于深度放电的电池,预充可以帮助激活电池的化学反应,恢复电池的正常工作状态。保护电池:防止因直接施加高电......
  • Oracle 11g 数据库内存原理
    转自:1、https://blog.csdn.net/ly7472712/article/details/1162393882、https://www.cnblogs.com/prognani/archive/2012/05/14/2500679.htmlOracle11g数据库内存管理-----------------------------------------------------------------------------一、Oracle数据库内......