某大厂一面:说说ThreadLocal的实现原理

news2025/1/23 14:00:39

ThreadLocal 是 Java 中一个非常有用的类,它提供了线程本地存储的功能。其作用是为每个线程提供独立的变量副本,使得不同线程访问时互不干扰。以下是 ThreadLocal 的详细原理:

1. ThreadLocal 类的基本作用

ThreadLocal 通过保证每个线程都能访问到它自己的一份副本来解决并发访问问题。每个线程都通过自己的 ThreadLocal 实例获取值,确保了线程之间的数据隔离和独立性。

ThreadLocal<Integer> threadLocal = new ThreadLocal<>();

每个线程在调用 threadLocal.get() 时,都会得到该线程私有的一个变量副本。ThreadLocal 的值对不同线程是独立的,线程A的ThreadLocal值与线程B的ThreadLocal值互不影响。

2. 内部实现原理

ThreadLocal 的核心思想是通过每个线程持有一个与该线程相关联的变量副本。这些副本是存储在每个线程的 Thread 对象中的。Java 是如何做到这一点的呢?

  • ThreadLocalMap: 每个线程 (Thread) 内部有一个 ThreadLocal.ThreadLocalMap。该映射的键是 ThreadLocal 对象,值是存储的线程私有数据。
  • Thread 类: Thread 类内部有一个 ThreadLocalMap 类型的字段。每个线程会有自己的 ThreadLocalMap,它存储了当前线程所有 ThreadLocal 变量的值。

3. 详细实现步骤

  1. 线程创建时初始化 ThreadLocalMap
    每个线程创建时,JVM 会为其分配一个 ThreadLocalMap,该 ThreadLocalMap 用于存储线程本地变量的值。

  2. 线程通过 setget 方法存取线程本地变量

    • 当调用 threadLocal.set(value) 时,JVM 会将当前线程作为键,ThreadLocal 实例作为值存入 ThreadLocalMap
    • 当调用 threadLocal.get() 时,JVM 会根据当前线程从其 ThreadLocalMap 中查找与当前 ThreadLocal 相关联的值。
  3. ThreadLocalMap 中的存储结构
    ThreadLocalMap 是一个基于数组的实现,内部使用了哈希表存储键值对。每个 ThreadLocal 对象对应一个线程本地变量的存储位置。

  4. 内存管理
    ThreadLocal 变量的值和线程绑定在一起,线程退出或结束时,相关联的 ThreadLocal 变量会被清理。这是通过 ThreadLocalMap 中的清理机制实现的。

    • 在垃圾回收中,ThreadLocal 本身作为 ThreadLocalMap 中的键不会被回收,除非手动清除。为了防止内存泄漏,Java 在清除 ThreadLocalMap 时会避免键(ThreadLocal)的强引用,使用弱引用来持有 ThreadLocal 对象。

4. 主要方法与工作流程

  • get()

    返回当前线程中与 ThreadLocal 相关联的值,如果没有则返回 null。其实现通过 ThreadLocalMap 查找当前线程的值。

  • set(T value)

    设置当前线程中与 ThreadLocal 相关联的值。

  • remove()

    移除当前线程中与 ThreadLocal 相关联的值。这样做可以避免内存泄漏,特别是在长生命周期的线程中。

5. 线程本地变量的生命周期与内存泄漏问题

  • 内存泄漏问题:如果在使用 ThreadLocal 时没有显式调用 remove() 方法,可能导致内存泄漏。虽然 ThreadLocalMap 会在线程结束时清理掉无用的线程本地变量,但是 ThreadLocal 对象本身会作为 ThreadLocalMap 的键被强引用,如果 ThreadLocal 对象的生命周期较长,可能会导致不必要的内存占用。

  • 清理机制:在 JDK 1.2 以后,为了避免内存泄漏,ThreadLocalMap 内部将 ThreadLocal 对象的引用方式改成了弱引用(WeakReference)。当 ThreadLocal 对象被垃圾回收时,它就会自动从 ThreadLocalMap 中移除。

6. 使用场景与注意事项

  • 线程池中使用 ThreadLocal:线程池中的线程是复用的,长时间存活的线程可能会有一些共享的线程本地变量。为了避免内存泄漏,需要特别注意清理工作。
  • 避免频繁使用ThreadLocal 是一种特殊的存储方式,过度依赖可能会使代码变得难以理解和调试。
  • 优化内存使用:可以通过合理设置线程本地变量的生命周期,减少不必要的内存占用。

7. 示例代码

public class ThreadLocalExample {
    // 创建 ThreadLocal 变量
    private static ThreadLocal<Integer> threadLocal = ThreadLocal.withInitial(() -> 0);

    public static void main(String[] args) {
        // 启动两个线程
        Thread thread1 = new Thread(() -> {
            threadLocal.set(1);  // 为当前线程设置值
            System.out.println("Thread 1 Value: " + threadLocal.get());
        });

        Thread thread2 = new Thread(() -> {
            threadLocal.set(2);  // 为当前线程设置值
            System.out.println("Thread 2 Value: " + threadLocal.get());
        });

        thread1.start();
        thread2.start();
    }
}

输出:

Thread 1 Value: 1
Thread 2 Value: 2

总结

ThreadLocal 提供了线程本地存储的能力,使得多线程之间的变量互不干扰。其底层通过 ThreadLocalMap 存储每个线程的局部变量,从而实现线程隔离。在多线程编程中,合理使用 ThreadLocal 可以避免共享数据带来的问题,但需要注意内存泄漏和清理工作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2280930.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

node.js 07.npm下包慢的问题与nrm的使用

一.npm下包慢 因为npm i 默认从npm官网服务器进行下包,但是npm官网服务器是海外服务器所以响应很慢. 于是我们通过npm下包的时候通常用淘宝镜像进行下包,下面是切换到淘宝镜像地址下包的操作. 二.nrm的使用 nrm是一个管理切换npm下包地址的工具,可以快速切换下包的地址. 安…

2025发文新方向:AI+量化 人工智能与金融完美融合!

2025深度学习发论文&模型涨点之——AI量化 人工智能的融入&#xff0c;使量化交易实现了质的突破。借助机器学习、深度学习等先进技术&#xff0c;人工智能可高效处理并剖析海量市场数据&#xff0c;挖掘出数据背后错综复杂的模式与趋势&#xff0c;从而不仅提升了数据分析…

【16届蓝桥杯寒假刷题营】第1期DAY5

5.依依的询问最小值 - 蓝桥云课 问题描述 依依有个长度为 n 的序列 a&#xff0c;下标从 1 开始。 她有 m 次查询操作&#xff0c;每次她会查询下标区间在 [li​,ri​] 的 a 中元素和。她想知道你可以重新排序序列 a&#xff0c;使得这 m 次查询的总和最小。 求你求出 m 次…

25/1/15 嵌入式笔记 初学STM32F108

GPIO初始化函数 GPIO_Ini&#xff1a;初始化GPIO引脚的模式&#xff0c;速度和引脚号 GPIO_Init(GPIOA, &GPIO_InitStruct); // 初始化GPIOA的引脚0 GPIO输出控制函数 GPIO_SetBits&#xff1a;将指定的GPIO引脚设置为高电平 GPIO_SetBits(GPIOA, GPIO_Pin_0); // 将GPIO…

C语言--数据在内存中的存储

数据在内存中的存储 主要研究整型和浮点型在内存中的存储。 1. 整数在内存中的存储 在学习操作符的时候&#xff0c;就了解过了下面的内容&#xff1a; 整数的2进制表示方法有三种&#xff0c;即原码、反码和补码。 有符号的整数&#xff0c;三种表示方法均有符号位和数值…

DRG_DIP 2.0时代医院程序结构转型与数据结构优化研究

一、引言 1.1 DRG_DIP 2.0 改革背景与意义 医保支付方式改革在医疗保障制度改革中占据着极为关键的地位&#xff0c;是推动医疗领域变革的核心力量。它犹如一把精准的手术刀&#xff0c;对医疗资源的合理分配、医疗服务质量的稳步提升以及医疗费用的有效控制起着决定性作用。…

炸场硅谷,大模型“蒸汽机”迎来“瓦特时刻”

作者 | 曾响铃 文 | 响铃说 中国大模型又在包括硅谷在内的全球AI圈炸场了。 两天前&#xff0c;幻方量化旗下AI公司深度求索&#xff08;DeepSeek&#xff09;&#xff0c;以及月之暗面相隔20分钟相继发布了自家最新版推理模型&#xff0c;分别是DeepSeek-R1以及Kimi 全新多…

【自动驾驶】4 智驾生态概述

目录 1 智驾生态概述 ▲ 关键组成部分 ▲ 概述 2 关键技术 ▲ 传感器 ▲ 感知 ▲ 数据闭环 3 未来市场 1 智驾生态概述 智能驾驶生态&#xff0c;简称智驾生态&#xff0c;是指围绕智能驾驶技术的开发、应用、服务和支持所形成的产业体系和合作网络。 涵盖了从硬件设…

Excel 技巧14 - 如何批量删除表格中的空行(★)

本文讲如何批量删除表格中的空行。 1&#xff0c;如何批量删除表格中的空行 要点就是按下F5&#xff0c;然后选择空值条件以定位所有空行&#xff0c;然后删除即可。 按下F5 点 定位条件 选 空值&#xff0c;点确认 这样就选中了空行 然后点右键&#xff0c;选 删除 选中 下方…

C语言进阶习题【1】指针和数组(4)——指针笔试题3

笔试题5&#xff1a;下面代码输出是是什么&#xff1f; int main() {int a[5][5];int(*p)[4];p a;printf( "%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);return 0; }分析 代码结果 笔试题6&#xff1a;下面代码输出是是什么&#xff1…

5. 推荐算法的最基础和最直观的认识

1.性别年龄转换为统一的计量单位 所谓推荐&#xff0c;就是替别人推荐&#xff0c;比如工厂A需要招男员工&#xff0c;希望大家推荐认识的人。那么在这里&#xff0c;就有了推荐的概念&#xff0c;限定条件是男。我们知道&#xff0c;人的性别一般分为男或者女。在这里假设把男…

如何在Matplotlib中绘制多个Y轴刻度

Matplotlib是一个功能强大的Python库&#xff0c;在它的帮助下&#xff0c;我们可以绘制条形图&#xff0c;图表&#xff0c;绘图&#xff0c;比例等。在本文中&#xff0c;我们将尝试在Matplotlib中绘制多个Y轴刻度。 为什么多个Y轴刻度很重要&#xff1f; 绘制具有不同单位…

大模型GUI系列论文阅读 DAY1:《基于大型语言模型的图形用户界面智能体:综述》(6.6W 字长文)

摘要 图形用户界面&#xff08;Graphical User Interfaces, GUIs&#xff09;长期以来一直是人机交互的核心&#xff0c;为用户提供了直观且以视觉为驱动的方式来访问和操作数字系统。传统上&#xff0c;GUI交互的自动化依赖于基于脚本或规则的方法&#xff0c;这些方法在固定…

RabbitMQ1-消息队列

目录 MQ的相关概念 什么是MQ 为什么要用MQ MQ的分类 MQ的选择 RabbitMQ RabbitMQ的概念 四大核心概念 RabbitMQ的核心部分 各个名词介绍 MQ的相关概念 什么是MQ MQ(message queue)&#xff0c;从字面意思上看&#xff0c;本质是个队列&#xff0c;FIFO 先入先出&am…

linux 下tensorrt的yolov8的前向推理(python 版本)的实现

一、yolov8的python实现的环境搭建 #通过pip安装 pip install ultralytics #通过git克隆GitHub仓库 git clone <https://github.com/ultralytics/ultralytics.git> cd ultralytics #安装依赖 pip install -r requirements.txt #执行推理 yolo predict model./yolov8n.pt …

java文件按行写入数据后并创建行索引及查询

背景 当有很多数据需要存储&#xff0c;这些数据只是想要简单的按行存储和查询&#xff0c;不需要进行其他条件搜索&#xff0c;此时就可以考虑不需把这些数据存储在数据库&#xff0c;而是直接写入文件&#xff0c;然后从文件中查询 但是正常情况下&#xff0c;如果仅仅只是按…

SpringBoot集成Flink-CDC,实现对数据库数据的监听

一、什么是 CDC &#xff1f; CDC 是Change Data Capture&#xff08;变更数据获取&#xff09;的简称。 核心思想是&#xff0c;监测并捕获数据库的变动&#xff08;包括数据或数据表的插入、 更新以及删除等&#xff09;&#xff0c;将这些变更按发生的顺序完整记录下来&…

VisualStudio中配置OpenGL环境并制作模板

VisualStudio中配置OpenGL环境并制作模板 本教程来自&#xff1a;sumantaguha Install Visual Studio Download Microsoft Visual Studio Community 2019 from https://my. visualstudio.com/Downloads?qvisual%20studio%202019&wt.mc_ idomsftvscom~older-downloads and…

工程上LabVIEW常用的控制算法有哪些

在工程应用中&#xff0c;LabVIEW常用的控制算法有很多&#xff0c;它们广泛应用于自动化、过程控制、机器人、测试测量等领域。以下是一些常见的控制算法&#xff1a; 1. PID 控制 用途&#xff1a;PID&#xff08;比例-积分-微分&#xff09;控制是最常用的反馈控制算法&…

WPF1-从最简单的xaml开始

1. 最简单的WPF应用 1.1. App.config1.2. App.xaml 和 App.xaml.cs1.3. MainWindow.xaml 和 MainWindow.xaml.cs 2. 正式开始分析 2.1. 声明即定义2.2. 命名空间 2.2.1. xaml的Property和Attribute2.2.2. xaml中命名空间2.2.3. partial关键字 学习WPF&#xff0c;肯定要先学…