ThreadLocal原理剖析

news2025/1/21 9:38:18

一.ThreadLocal的含义

ThreadLocal也就是线程本地变量,创建了一个ThreadLocal变量,访问这个变量的每个线程都会有这个变量的一个本地拷贝,多个线程操作这个变量的时候,实际上是操作自己本地内存里面的变量,从而起到线程隔离的作用,避免了线程安全问题。

  public static void main(String[] args) {
        ThreadLocal<Integer>local=new ThreadLocal<>();
        Thread thread1=new Thread(()->{
            System.out.println(local.get());
            local.set(1);
            System.out.println(local.get());
        });
        Thread thread2=new Thread(()->{
            System.out.println(local.get());
            local.set(2);
            System.out.println(local.get());
        });
        thread1.start();
        thread2.start();
    }

我们看到thread1对local变量值的修改并没有影响thread2线程的local变量

 

线程thread1和线程thread2从主内存中分别读取一份数据作为副本到本地的工作内存,然后去使用这个变量,变量之间并不会相互影响

二.ThreadLocal底层结构

ThreadLocal底层是通过ThreadLocalMap来实现的,每个Thread对象中都存在一个ThreadLocalMap,Map的key为ThreadLocal对象,Map的value为需要缓存的值

三.ThreadLocal发生内存泄露的原因,以及解决办法

我们先来看一段代码

  public static final ThreadLocal<byte[]>local=new ThreadLocal<>();
public static void main(String[] args) {
       
      ExecutorService service=Executors.newFixedThreadPool(5);

        for(int i=0;i<100;i++)
        {
            service.execute(()->{
                local.set(new byte[50240*10240]);
            });

        }
        service.shutdown();
    }

我们创建了一个线程池,去给这个local变量value值赋值,最后运行程序,我们发现栈溢出了

 nhxi 

那这又是因为什么呢?我们先来看一张图

 

 我们的线程对象是通过强引用指向ThreadLocalMap,而ThreadLocalMap也是通过强引用指向Entry对象,线程不被回收,Entry对象也不会被gc回收,当Entry对象越来越多,就造成内存泄漏

那如何解决这个问题呢?只需要我们手动释放ThreadLocal对象就可以了。

  public static final ThreadLocal<byte[]>local=new ThreadLocal<>();
    public static void main(String[] args) {

      ExecutorService service=Executors.newFixedThreadPool(5);

        for(int i=0;i<100;i++)
        {
            service.execute(()->{
                local.set(new byte[50240*10240]);
                local.remove();//手动释放local对象
            });

        }
        service.shutdown();
    }

四.ThreadLocalMap的哈希冲突解决

ThreadLocalMap使用开放地址法来解决Hash冲突的问题,会将当前插入元素从冲突位置开始依次往后遍历,直到找到一个空闲的位置,然后把元素放在这个空闲位置

五.ThreadLocalMap扩容机制

ThreadLocalMap扩容机制和HashMap类似,也就是在元素数量达到阈值(通常为数组的3/4)时 

进行扩容,在set()方法中,如果当前元素已经达到了阈值,就会调用rehash方法,rehash方法先会清理过期的Entry,然后判断size是否>=3/4threshold如果大于则进行扩容,然后进行重新哈希,此时新数组长度为原来的2倍

 

 

六.ThreadLocal如何实现父子线程通信

Thread类当中存在InheritableThreadLocal变量,也就是说使用InheritableThreadLocal来进行传递,当父线程的InheritableThreadLocal不为空时,就会将这个值传到当前子线程InheritableThre 

dLocal

public static void main(String[] args) {
        ThreadLocal<String>threadLocal=new ThreadLocal<>();
        threadLocal.set("threadlocal");
        ThreadLocal<String>inheritableThreadLocal=new InheritableThreadLocal<>();
        inheritableThreadLocal.set("inheritableThreadLocal");
        Thread thread=new Thread(()->{
            System.out.println(threadLocal.get());
            System.out.println(inheritableThreadLocal.get());
        });
        thread.start();
    }

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

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

相关文章

基于单片机的简易智能电动车设计

一、项目介绍 智能交通工具在现代社会中起着越来越重要的作用&#xff0c;电动车作为一种环保、便捷的交通工具&#xff0c;受到了广泛的关注和应用。本设计基于单片机技术&#xff0c;设计一款简易智能电动车&#xff0c;实现基本的控制和功能&#xff0c;并提供良好的用户体…

kubectl入门

一.kubectl的三种资源管理方式&#xff1a; 二. kubectl资源介绍&#xff1a; 1.namespace&#xff1a;实现多套环境的资源隔离或者多租户的资源隔离。k8s中的pod默认可以相互访问&#xff0c;如果不想让两个pod之间相互访问&#xff0c;就将其划分到不同ns下。 2.pod&#x…

搭建Python开发环境

开发环境 Python是一种跨平台 的编程语言&#xff0c;这意味着它能够在所有的主流操作系统中运行&#xff0c;开发者可以Windows、Linux、Mac中开发和学习Python&#xff0c;甚至在Android手机中也可以运行Python代码。 在所有安装了Pythonr现代计算机上&#xff0c;都能够运…

华为OD:敏感字段加密

题目描述&#xff1a; 给定一个由多个命令字组成的命令字符串&#xff1a; 1、字符串长度小于等于127字节,只包含大小写字母,数字,下划线和偶数个双引号&#xff1b; 2、命令字之间以一个或多个下划线_进行分割&#xff1b; 3、可以通过两个双引号”"来标识包含下划线…

自定义创建项目

基于VueCli自定义创建项目 1.Eslint代码规范 代码规范:一套写代码的约定规则。 比如 赋值符号的左右是否需要空格 一句话结束是否要加&#xff1b; 正规的团队 需要统一的编码风格 https://standardjs.com/rules-zhcn.html 规则查找 https://zh-hans.eslint.org/docs/late…

CESM2代码下载

这半年忙着毕业写论文&#xff0c;好久好久好久不更新了∠( ω)&#xff0f; &#xff0c;今天准备开个新坑 ๑乛◡乛๑&#xff0c;学习一下CESM&#xff08;Community Earth System Model&#xff09;&#xff0c;它是一个完全耦合的全球气候模型&#xff0c;可用于地球过去、…

千纸鹤APP云验证系统源码 APK注入引流弹窗

千纸鹤APP云验证系统是一款全面的验证系统&#xff0c;包括网络验证、APK注入、注册机、引流弹窗、更新弹窗等功能。该系统提供完整的源代码&#xff0c;方便开发者二次开发和定制化需求。 可以对用户进行多种验证&#xff0c;包括账号密码验证、短信验证码验证等。该系统还提供…

jmeter 常数吞吐量定时器

模拟固定吞吐量的定时器。它可以控制测试计划中各个请求之间的时间间隔&#xff0c;以达到预期的吞吐量。 参数包括&#xff1a; Target Throughput&#xff1a;目标吞吐量&#xff08;每分钟请求数&#xff09;Calculate Throughput based on&#xff1a;吞吐量计算基准&…

机器人中的数值优化(七)——修正阻尼牛顿法

本系列文章主要是我在学习《数值优化》过程中的一些笔记和相关思考&#xff0c;主要的学习资料是深蓝学院的课程《机器人中的数值优化》和高立编著的《数值最优化方法》等&#xff0c;本系列文章篇数较多&#xff0c;不定期更新&#xff0c;上半部分介绍无约束优化&#xff0c;…

2023开学礼《乡村振兴战略下传统村落文化旅游设计》许少辉八一新书南京师范大学图书馆

2023开学礼《乡村振兴战略下传统村落文化旅游设计》许少辉八一新书南京师范大学图书馆

程序员工作技巧

提高工作技巧的秘方 案例 让我们猜测一下 绵羊想表达的什么&#xff1f; 并不够准确 崩了&#xff0c;不能用了整个业务瘫痪了研发没有责任感 语义规则/模棱俩可 相对语言 量化数据表达&#xff1a;疼苦指数&#xff0c;拥堵指数&#xff0c;准确。 尽量减少标签化评价 标签…

iPhone 隔空投送使用指南:详细教程

本文介绍了如何在iPhone上使用隔空投送,包括如何在iOS 11到iOS 14的iPhone上启用它、发送文件以及接受或拒绝AirDrop发送给你的文件。对于iOS 7以上的旧款iPhone,提供了另一种方法。 如何打开隔空投送 你可以通过以下两种方式之一启动隔空投送功能:在“设置”应用程序或控…

[dasctf]misc05

盲水印 png里藏jpg&#xff0c;bwm.py可以提取含flag的图片

无涯教程-JavaScript - NORMDIST函数

NORMDIST函数替代Excel 2010中的NORM.DIST函数。 描述 该函数返回指定均值和标准差的正态分布。此功能在统计中有非常广泛的应用,包括假设检验。 语法 NORMDIST(x,mean,standard_dev,cumulative)争论 Argument描述Required/OptionalXThe value for which you want the dis…

代码数据会促进LLM的推理能力吗?

深度学习自然语言处理 原创作者&#xff1a;Winnie 代码数据对提升LLM的推理能力有效吗&#xff1f;为了解答这个问题&#xff0c;最近的一篇工作提出了CIRS&#xff08;复杂度影响推理分数&#xff09;这一新的指标&#xff0c;用来衡量代码数据的复杂性&#xff0c;进而验证不…

Ae 效果:CC Light Rays

生成/CC Light Rays Generate/CC Light Rays CC Light Rays&#xff08;CC 光线&#xff09;可以创建从光源发出并能穿过图层内容的光线效果。常用于制作光线透过门窗或云层的场景&#xff0c;或者用于创建神奇或梦幻的氛围感。 本效果会被限制在源图层的大小范围之内。 ◆ ◆…

采用ROUANT 方法对 nex-gddp-cmip6 数据进行精度校正

专题一 CMIP6中的模式比较计划 1.1 GCM介绍全球气候模型&#xff08;Global Climate Model, GCM&#xff09;&#xff0c;也被称为全球环流模型或全球大气模型&#xff0c;是一种用于模拟地球的气候系统的数值模型。这种模型使用一系列的数学公式来描述气候系统的主要组成部分…

maven搭建spring项目

前提 安装jdk 安装maven 安装eclipse 创建maven项目 搭建spring项目 pom.xml <dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.0.4.RELEASE</version> </dependency&…

RobotFramework中的常用变量

文章目录 前言 一 标量&#xff0c;列表和字典1. Scalar 变量1.1 在变量文件&#xff08;Variables&#xff09;中使用1.2 在测试用例&#xff08;TestCases&#xff09;中使用1.3 Scalar 变量的相关操作 2. List 变量2.1 在变量文件&#xff08;Variables&#xff09;中使用2.…