谈一谈Java的ThreadLocal

目录

先说原理:

再上代码:

运行结果:


先说原理:

ThreadLocal 是一个本地线程副本变量工具类,它可以在每个线程中创建一个副本变量,每个线程可以独立地修改自己的副本变量,而不会影响其他线程的副本变量。它的实现原理可以简单概括如下:

  1. ThreadLocal 内部维护了一个 Map 对象,用于存储每个线程的副本变量。Map 的键为线程对象,值为对应线程的副本变量。
  2. 在每个线程中,ThreadLocal 实例会创建一个唯一的 ThreadLocalMap 对象,用于存储该线程的所有副本变量。ThreadLocalMap 是一个自定义的哈希表数据结构继承自 WeakReference,它的键为 ThreadLocal 对象,值为对应线程的副本变量。
  3. 在创建 ThreadLocal 实例时,实际上是在当前线程的 ThreadLocalMap 中新增一个键值对,其中键为当前 ThreadLocal 对象,值为初始化的副本变量。
  4. 当需要获取当前线程的副本变量时,ThreadLocal 实例会先获取当前线程的 ThreadLocalMap,再通过当前 ThreadLocal 对象作为键来获取对应的副本变量。由于每个线程独立维护自己的 ThreadLocalMap,所以不同线程的相同 ThreadLocal 对象对应的副本变量也是不同的。
  5. 当一个线程结束时,它持有的所有 ThreadLocalMap 中的键值对会成为垃圾对象,但由于 ThreadLocalMap 的键是 WeakReference 类型,所以这些键可能被垃圾回收器回收,但值对象不会被回收,从而导致内存泄漏。为了解决这个问题,ThreadLocal 内部使用了 ThreadLocalMapexpungeStaleEntry() 方法,定期清除废弃的键值对。

总的来说,ThreadLocal 通过维护一个 Map,为每个线程创建一个独立的 ThreadLocalMap,并使用弱引用来避免内存泄漏,从而实现了在每个线程中创建独立的副本变量,并提供了线程安全的访问方式。

再上代码:

package cn.net.cdsz.ccb.test;

import java.io.IOException;
import java.io.PipedReader;
import java.io.PipedWriter;

public class test {

        static class ThreadA implements Runnable {
            private ThreadLocal<String> threadLocal;

            public ThreadA(ThreadLocal<String> threadLocal) {
                this.threadLocal = threadLocal;
            }

            @Override
            public void run() {
                threadLocal.set("A");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("ThreadA输出:" + threadLocal.get());
            }
        }
        static class ThreadB implements Runnable {
            private ThreadLocal<String> threadLocal;
            public ThreadB(ThreadLocal<String> threadLocal) {
                this.threadLocal = threadLocal;
            }
            @Override
            public void run() {
                threadLocal.set("B");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("ThreadB输出:" + threadLocal.get());
            }
        }
        public static void main(String[] args) {
            ThreadLocal<String> threadLocal = new ThreadLocal<>();
            new Thread(new ThreadA(threadLocal)).start();
            new Thread(new ThreadB(threadLocal)).start();
        }

}

运行结果:

最常⻅的ThreadLocal使⽤场景为⽤来解决数据库连接、Session管理等。数据库连
接和Session管理涉及多个复杂对象的初始化和关闭。如果在每个线程中声明⼀些
私有变量来进⾏操作,那这个线程就变得不那么“轻量”了,需要频繁的创建和关闭
连接。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

测试的价值不仅仅是找

测试的价值不仅仅是找Bug 在我测试工作的前5年&#xff0c;一直以为测试的目标和价值就是在黑盒测试活动中找bug&#xff0c;以找到bug越多越自豪。但当我随着商业意识的不断积累&#xff0c;跳出测试的视角&#xff0c;站在公司的角度看测试时&#xff0c;会发现测试的目标是商…

linux驱动学习加强版-5(ioctl的使用)

文章目录一、添加ioctl控制节点二、修改测试APP2.1 测试APP的代码&#xff1a;2.2 驱动代码&#xff1a;ioctl是用户空间和内核空间相互交流时候用的比较多的一种手段。我们也可以在HAL层通过ioctl调到驱动里面。一、添加ioctl控制节点 先看patch 吧 这是在驱动中添加的ioct…

个人-计算机操作系统第五章

第五章 虚拟存储器 一、章节练习 1.系统抖动是指( )。 A. 使用机器时&#xff0c;千万屏幕闪烁的现象 B. 刚被调出的页面又立刻被调入所形成的频繁调入调出现象 C. 系统盘不净&#xff0c;千万系统不稳定的现象 D. 由于内存分配不当&#xff0c;偶然造成内存不够…

02-神经网络基础

一、从机器学习到神经网络 1. 两层神经网络 - 多层感知机 2. 浅层神经网络特点 (1)需要数据量小、训练速度快; (2)对复杂函数的表示能力有限,泛化能力受到制约。 Kurt Hornik 证明了理论上两层神经网络足以拟合任意函数,而且过去没有足够的数据和计算能力,因此之前的…

兰伯特光照模型(Lambert Lighting)和半兰伯特光照模型(Half-Lanbert)

关于漫反射 光打到凹凸不平的平面上&#xff0c;光线会被反射到四面八方&#xff0c;被称为漫反射 关于这种模型&#xff0c;由于光线由于分散&#xff0c;所以进入人眼的光线强度和观察角度没有区别 在A点和B点接收到的光线强度是一样的 在漫反射下&#xff0c;光线强度只和光…

卫龙携手契约锁,推动人事、采购、销售业务电子签

知名辣味休闲食品企业——卫龙&#xff0c;携手契约锁就印章管控及电子签章技术展开合作&#xff0c;打造覆盖总部及20多家子公司的印章管控平台&#xff0c;以现有泛微OA、钉钉APP为基础&#xff0c;推动人事、采购、销售业务电子签&#xff0c;通过签字、盖章无纸化&#xff…

使用Navicat进行ssh通道连接MySQL数据库

1、正常打开连接窗口&#xff0c;选择SSH&#xff1b; 2、填写完SSH对应参数&#xff0c;重新选择常规&#xff1b; SSH参数&#xff1a; 主机 > 服务器IP 端口 > 22 【一般22&#xff0c;SSH监听端口】 用户名 > 登录服务器账户 密码 > 登录服务器密码常规的参数…

mplfinancet绘制K线图

mplfinancet绘制K线图 1、安装 安装速度快 pip install mplfinance -i https://pypi.tuna.tsinghua.edu.cn/simple C:\Users>pip install mplfinance -i https://pypi.tuna.tsinghua.edu.cn/simple Defaulting to user installation because normal site-packages is not …

35岁的测试工程师被公司强行辞退,感叹道:我以前就该好好努力了

曾经的高薪软件测试工程师&#xff0c;今年35岁了&#xff0c;被公司劝退了&#xff0c;外卖跑到凌晨&#xff0c;很累&#xff0c;但还是有一种想诉说的冲动。哪怕让大家觉得已经说得太多了&#xff0c;烦了&#xff0c;都成祥林嫂了&#xff0c;但是&#xff0c;我是真的想说…

js:手写一个promise

背景 promise 作为前端开发中常用的函数&#xff0c;解决了 js 处理异步时回调地狱的问题&#xff0c;大家应该也不陌生了&#xff0c;今天来学习一下 promise 的实现过程&#xff0c;这样可以加&#xff08;面&#xff09;深&#xff08;试&#xff09;理&#xff08;要&…

第八天并发编程篇

一、简述线程、进程、程序的基本概念&#xff1f; 1.进程&#xff1a; 我们把运行中的程序叫做进程,每个进程都会占用内存与CPU资源,进程与进程之间互相独立. 2.线程&#xff1a; 线程就是进程中的一个执行单元&#xff0c;负责当前进程中程序的执行。一个进程可以包含多个线程…

Matlab在线IDE:计算定积分上限

上一篇文章&#xff1a;Matlab在线IDE&#xff1a;MATLAB Online介绍与计算定积分案例 1、案例介绍 % 定义符号变量 x syms x;% 定义函数 f(x) x f x;% 定义定积分的值 I I 2;% 计算函数 f(x) 在 [0, x] 区间的定积分&#xff0c;并求其反函数 F(x) F finverse(int(f, 0, …

【hello Linux】Linux软件管理器yum

目录 1.Linux软件管理器yum 1.1 关于lrzsz 1.2 使用yum时的注意事项 1.3 查看软件包&#xff1a;yum list 1.4 安装软件&#xff1a;yum install 1.5 卸载软件&#xff1a;yum remove 1.6 更新yum源 1.7 实战项目 Linux&#x1f337; 1.Linux软件管理器yum 在windows系统下有应…

ROS学习——艰辛的环境安装之路一Ubuntu

文章目录Ubuntu安装和下载页面设置安装Vmware Tools安装VSCODE用几个常用命令简单熟悉下UbuntuUbuntu 安装和下载 Ubuntu的安装和下载 看这个链接 Ubuntu安装和下载1 或者这个链接 Ubuntu安装和下载2 页面设置 安装Vmware Tools 看这个链接 VMware Tools的介绍和安装 安装…

超详细从入门到精通,pytest自动化测试框架实战-pytest插件的开发(八)

目录&#xff1a;导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;前言 pytest框架采用的是…

3年测试经验只会“点点点”,不会自动化即将面临公司淘汰?沉淀100天继续做测试

前段时间一个朋友跟我吐槽&#xff0c;说自己做软件测试工作已经3年了&#xff0c;可这三年自己的能力并没有得到提升&#xff0c;反而随着互联网的发展&#xff0c;自己只会“点点点”的技能即将被淘汰。说自己很苦恼了&#xff0c;想要提升一下自己&#xff0c;可不知道该如何…

简单的做一个学校毕业啊项目

前言&#xff1a;相信看到这篇文章的小伙伴都或多或少有一些编程基础&#xff0c;懂得一些linux的基本命令了吧&#xff0c;本篇文章将带领大家服务器如何部署一个使用django框架开发的一个网站进行云服务器端的部署。 文章使用到的的工具 Python&#xff1a;一种编程语言&…

每日一练——Day 13

前言&#xff1a; 小亭子正在努力的学习编程&#xff0c;接下来将开启编程题的练习~~ 分享的文章都是学习的笔记和感悟&#xff0c;如有不妥之处希望大佬们批评指正~~ 同时如果本文对你有帮助的话&#xff0c;烦请点赞关注支持一波, 感激不尽~~ 第一题 题目描述&#xff1a; 刷…

SpringBoot基础学习之(十二):通过spring boot框架连接MySql数据库(通过idea中的工具Database连接Mysql数据库)

Springboot这个系列实现的案例&#xff1a;员工后台管理系统 之前讲解的内容是前后端的交互&#xff0c;并没有涉及到数据库。把员工信息放置在一个数组中&#xff0c;实现的方法则是对数组的增删改查操作&#xff0c;但是从今天开始&#xff0c;实现的功能则是在数据库的基础上…

Qt Quick - ToolTip

Qt Quick - ToolTip使用总结一、概述二、附带的ToolTip三、延迟和超时四、自定义ToolTip五、定制化一、概述 ToolTip 其实就是ToolTip&#xff0c;所谓ToolTip其实就是一段简短的文本&#xff0c;告知用户控件的功能。它通常置于父控件之上或之下。提示文本可以是任何富文本格…