ThreadLocal类的实例解析以及常用方法通过具体案例了解ThreadLocal的基本使用

news2024/11/28 14:35:30

目录

前言

一、ThreadLocal 分析

二、ThreadLocal的基本使用

三、实现原理

四、存在问题

        1.引用

2.问题详情

3.解决方案

五、章末


前言

        小伙伴们大家好,谈到多线程就不可不谈解决线程安全 的操作类ThreadLocal了

一、ThreadLocal 分析

        ThreadLocal会为每个线程分配独立的线程副本,解决并发访问冲突的问题,并且实现线程内的资源共享。

        举个例子,刚开始学Java的时候都少不了手动连接数据库吧,创建连接,填写用户名密码等(霍 死去的物种连接数据库库方式开始攻击我)

       回归正题, JDBC 操作数据库不可或缺的工具,底层就是将线程的Connection放入各自的ThreadLocal当中,保证了每个线程都在自己的Connection上操作数据库,避免了误操作;

二、ThreadLocal的基本使用

        常见的方法有三个,set(),get(),remove(),以下案例是具体使用

public class ThreadLocalTest {
    static ThreadLocal<String> threadLocal = new ThreadLocal<>();

    public static void main(String[] args) {
        new Thread(()->{
            String name = Thread.currentThread().getName();
            threadLocal.set("test_1");
            printThread(name);
            System.out.println(name + " after remove :"+threadLocal.get());
        },"t1").start();

        new Thread(()->{
            String name = Thread.currentThread().getName();
            threadLocal.set("test_2");
            printThread(name);
            System.out.println(name + " after remove :"+threadLocal.get());
        },"t2").start();
    }

    static void printThread(String str){
        //打印当前线程本地变量的值
        System.out.println(str + " :"+threadLocal.get());
        //清除本地变量的值
        threadLocal.remove();

    }

}

        分析

        新建一个测试类,实例化一个threadLocal对象,泛型表示只能赋值字符串变量,main方法内新建两个线程,线程的操作是一样的,先获取当前线程的名称,threadLocal给本地变量赋值,打印并清除线程的本地变量的值,之后再次打印;

三、实现原理

        点击进入set(),里面用到了createMap(),再次点击,实例化了ThreadLocalMap对象,再次点击,终于到了底层(初步的底层)创建了一个table数组,这里才是真正存储数据的位置;(说句题外话,疯狂套娃呢搁着(bushi),不过挺有意思的,就像每次都发现新大陆一样)

四、存在问题

        1.引用

        万物不可能十全十美,ThreadLocal对象也一样,伴随着内存泄漏问题 ,先科普一波java对象的四种引用

  1. 强引用(Strong Reference):在程序中正常使用的对象引用都是强引用。如果一个对象被一个强引用所引用,那么这个对象就不会被回收,即使内存空间不足时也不会被回收。当强引用指向的对象不再被使用,或者被赋值为 null 时,垃圾回收器才会回收该对象。

  2. 软引用(Soft Reference):软引用用于描述还有用但并非必需的对象。软引用关联的对象只有在内存不足时才会被回收。当垃圾回收器开始回收内存时,软引用所引用的对象会被保留直至内存确实不足时才会被回收。

  3. 弱引用(Weak Reference):弱引用用于描述非必需对象,它比软引用更加弱化。被弱引用关联的对象只有在垃圾回收器运行时才会被回收。垃圾回收器在处理弱引用时,不论内存是否充足,都会回收它所引用的对象。

  4. 虚引用(Phantom Reference):虚引用也称为幽灵引用,它是最弱的一种引用类型。虚引用关联的对象完全没有被引用,只有当其所关联的对象被垃圾回收器回收时才会被加入到引用队列中。虚引用的作用是在对象被销毁之前给出一个通知,可以在对象被销毁后进行一些清理操作。

        什么?不想咬文嚼字?伪代码来了

  •  强引用:User user = new User(); 这种方式就是强引用
  •  弱引用:WeakReference weak = new WeakReference(user);这种就是弱引用了
2.问题详情

        ThreadLocal在保存的时候会把自己当做Key存在ThreadLocalMap中,正常情况应该是key和value都应该被外界强引用才对,但是现在key被设计成WeakReference弱引用了。 这就导致了⼀个问题,ThreadLocal在没有外部强引用时,发生GC时会被回收,如果创建ThreadLocal的线程⼀直持续运行,那么这个Entry对象中的value就有可能⼀直得不到回收,发⽣内存泄露。

        就比如线程池里面的线程,线程都是复用的,那么之前的线程实例处理完之后,出于复用的目的线程依然存活,所以,ThreadLocal设定的value值被持有,导致内存泄露。

3.解决方案

        方法是有的,因为按照道理⼀个线程使用完,ThreadLocalMap是应该要被清空的,但是现在线程被复用了,所以在代码的最后使用remove就好了,我们只要记得在使用的最后用remove把值清空就好了 ,like this, 务必手动remove();

ThreadLocal<String> threadLocal = new ThreadLocal();

try{

        threadLocal.set("AA");

        ...业务逻辑

} finally{

        threadLocal.remove();

}

五、章末

        好了,文章到这里就结束了。


 

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

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

相关文章

Linux实用操作

一、各类小技巧&#xff08;快捷键&#xff09; 1.1 ctrl c 强制停止 Linux某些程序的运行&#xff0c;如果想要强制停止它&#xff0c;可以使用快捷键ctrl c 命令输入错误&#xff0c;也可以通过快捷键ctrl c&#xff0c;退出当前输入&#xff0c;重新输入 1.2 ctrl d…

Linux C/C++ 从内存转储中恢复64位ELF可执行文件

ELF&#xff08;Executable and Linking Format&#xff09;是一种对象文件的格式&#xff0c;它主要用于定义ELF&#xff08;Executable and Linking Format&#xff09;是一种对象文件的格式&#xff0c;它主要用于定义不同类型的对象文件中的内容以及它们的存储方式。一个EL…

Jenkins参数化构建及代码发布

如何使用gitlab--web端可以观看此篇教程 https://blog.csdn.net/m0_59933574/article/details/134528050?spm1001.2014.3001.5502https://blog.csdn.net/m0_59933574/article/details/134528050?spm1001.2014.3001.5502 整体思路 依赖环境及工具 Git Centos7及以上 Gitla…

【利用二手车数据进行可视化分析】

利用二手车数据进行可视化分析 查看原始数据去除重复数据需求分析1.统计全国总共有多少量二手车&#xff0c;用KPI图进行展示2.统计安徽总共有多少量二手车&#xff0c;用KPI图进行展示3.统计合肥总共有多少量二手车&#xff0c;用KPI图进行展示4.取最贵的10辆二手车信息&#…

STM32——继电器

继电器工作原理 单片机供电 VCC GND 接单片机&#xff0c; VCC 需要接 3.3V &#xff0c; 5V 不行&#xff01; 最大负载电路交流 250V/10A &#xff0c;直流 30V/10A 引脚 IN 接收到 低电平 时&#xff0c;开关闭合。

[论文阅读]BEVFusion

BEVFusion BEVFusion: A Simple and Robust LiDAR-Camera Fusion Framework BEVFusion&#xff1a;简单而强大的激光雷达相机融合框架 论文网址&#xff1a;BEVFusion 论文代码&#xff1a;BEVFusion 简读论文 论文背景&#xff1a;激光雷达和摄像头是自动驾驶系统中常用的两…

【数值计算方法(黄明游)】函数插值与曲线拟合(二):三次 Hermite 插值【理论到程序】

​ 文章目录 一、近似表达方式1. 插值&#xff08;Interpolation&#xff09;2. 拟合&#xff08;Fitting&#xff09;3. 投影&#xff08;Projection&#xff09; 二、Lagrange插值1. 拉格朗日插值方法2. Lagrange插值公式a. 线性插值&#xff08;n1&#xff09;b. 抛物插值&…

ISP IC/FPGA设计-第一部分-MT9V034摄像头分析(0)

MT9V034为CMOS图像传感器&#xff0c;有着极其优秀的图像成像性能&#xff0c;同时支持丰富的功能用于isp的开发&#xff1b;MT9V034 的HDR宽动态、10bit数据深度、RAW格式&#xff08;bayer阵列&#xff09;图像、dvp和lvds接口、60fps正是学习isp开发的理想传感器&#xff1b…

接触刚性环境任务下的机器人力控(阻抗)性能测试

内涵 接触刚性环境任务下的机器人力控&#xff08;阻抗&#xff09;性能测试旨在评估机器人在与刚性物体交互时的性能表现。这种测试通过调整机器人的控制参数&#xff0c;如期望刚度和期望阻尼等&#xff0c;并分析记录的数据&#xff0c;旨在确保机器人能够在执行任务时保持…

快速测试 3节点的redis sentinel集群宕机2个节点以后是否仍能正常使用

有同事问我&#xff0c;三个redis sentinel节点&#xff0c;宕机两个节点以后&#xff0c;是否还能够正常的通过redis sentinel正常访问redis的数据。我想了想&#xff0c;理论上是可以的&#xff0c;但是我没试过&#xff0c;今天有时间就测试了一下。搭建环境和测试代码的过程…

4 向微服务架构转变

文章目录 小型单体系统为什么选择小型单体系统微服务与生俱来的问题小型单体系统适用于小团队拥抱重构 规划未来拆分的小型单体应用程序新需求和游戏化用户故事游戏化&#xff1a;积分、徽章和排行榜 转向微服务独立的工作流程水平可伸缩性细粒度的非功能需求其他优势劣势 架构…

一文搞懂Lombok Plugins使用与原理

目录 一文搞懂Lombok使用与原理 1.前言2.什么是Lombok3. IntelliJ安装Lombok3.1通过IntelliJ的插件中心安装3.2在项目中使用Lombok Plugins 4.Lombok 注解大全说明4.1POJO类常用注解4.2其他注解 5.Lombok常见问题6.总结7.参考 文章所属专区 超链接 1.前言 2.什么是Lombok Lo…

MyBatis 四大核心组件之 Executor 源码解析

&#x1f680; 作者主页&#xff1a; 有来技术 &#x1f525; 开源项目&#xff1a; youlai-mall &#x1f343; vue3-element-admin &#x1f343; youlai-boot &#x1f33a; 仓库主页&#xff1a; Gitee &#x1f4ab; Github &#x1f4ab; GitCode &#x1f496; 欢迎点赞…

EP15:动态内存管理概述(c语言)malloc,calloc,realloc函数的介绍使用及柔性数组的介绍

如果学习方向是c方向那么c语言有三个板块的知识是非常重要的. 1:指针 2:结构体 3;动态内存管理. 序言:在c语言中,什么是动态内存 C语言中的动态内存是指在程序运行时&#xff0c;根据需要动态地分配内存空间的一种内存管理方式。与静态内存相比&#xff0c;动态内存的大小和生…

美化博客园的个人主页

进入博客园个人主页 将博客皮肤改为&#xff1a;SimpleMemory 然后打开github网站&#xff1a;Cnblogs-Theme-SimpleMemory/docs/v2/Docs/GettingStarted/install.md at v2 BNDong/Cnblogs-Theme-SimpleMemory (github.com) 按照他上面写的做进行了&#xff1a; 复制到&#…

二叉搜索树中第K小的元素[中等]

优质博文&#xff1a;IT-BLOG-CN 一、题目 给定一个二叉搜索树的根节点root&#xff0c;和一个整数k&#xff0c;请你设计一个算法查找其中第k个最小元素&#xff08;从1开始计数&#xff09;。 示例 1&#xff1a; 输入&#xff1a;root [3,1,4,null,2], k 1 输出&#x…

Spring Boot 3 集成 MyBatis详解

MyBatis是一款开源的持久层框架&#xff0c;它极大地简化了与数据库的交互流程。与类似Hibernate的ORM框架不同&#xff0c;MyBatis更具灵活性&#xff0c;允许开发者直接使用SQL语句与数据库进行交互。Spring Boot和MyBatis分别是两个功能强大的框架&#xff0c;它们的协同使用…

SVN修改已提交版本的日志方法

1.在工做中一直是使用svn进行項目的版本控制的&#xff0c;有时候因为提交匆忙&#xff0c;或是忘了添加Log&#xff0c;或是Log内容有错误。遇到此类状况&#xff0c;想要在查看项目的日志时添加log或是修改log内容&#xff0c;遇到以下错误&#xff1a; Repository has not b…

[强网拟态决赛 2023] Crypto

文章目录 Bad_rsaClasslcal Bad_rsa 题目描述&#xff1a; from Crypto.Util.number import *f open(flag.txt,rb) m bytes_to_long(f.readline().strip())p getPrime(512) q getPrime(512) e getPrime(8) n p*q phi (p-1)*(q-1) d inverse(e,phi) leak d & ((1…

c语言一维数组总结详解

目录 介绍&#xff1a; 一维整型数组&#xff1a; 声明&#xff1a; 初始化&#xff1a; 打印输出&#xff1a; 输出结果&#xff1a; 浮点型数组&#xff1a; 代码&#xff1a; 运行结果&#xff1a; 补充&#xff1a; 一维字符数组&#xff1a; 字符数组声明及初始…