ThreadLocal原理

ThreadLocal实现原理 ThreadLocal和其他并发工具一样,也是用于解决多线程并发訪问。ThreadLocal通过为每个线程都提供了变量的副本,使得每个线程在同一时间访问的并非同一个数据,从而隔离了多个线程对数据的数据共享。 ThreadLocal的使用 ThreadLocal 类接口只提供了4个方法: public void set(Object value),设置当前线程的线程局部变量的值。 public Object get(),该方法返回当前线程... 阅读详情

一、TreadLocal介绍

JDK 1.2的版本中就提供java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一种新的思路。使用这个工具类可以很简洁地编写出优美的多线程程序,ThreadLocal并不是一个Thread,而是Thread的局部变量。

ThreadLocal的四个方法:

public T get()//获取ThreadLocal中当前线程共享变量的值
void set(Object value)//设置ThreadLocal中当前线程共享变量的值
public void remove()//移除ThreadLocal中当前线程共享变量的值
protected Object initialValue()// ThreadLocal没有被当前线程赋值时或当前线程刚调用remove方法后调用get方法,返回此方法值

二、ThreadLocal的使用

在有一种情况之下,我们需要满足这样一个条件:变量是同一个,但是每个线程都使用同一个初始值,也就是使用同一个变量的一个新的副本。这种情况之下ThreadLocal就非常使用,比如说DAO的数据库连接,我们知道DAO是单例的,那么他的属性Connection就不是一个线程安全的变量。而我们每个线程都需要使用他,并且各自使用各自的。这种情况,ThreadLocal就比较好的解决了这个问题。
代码实现如下:

public final class ConnectionUtil {

    private ConnectionUtil() {}

    private static final ThreadLocal<Connection> conn = new ThreadLocal<>();

    public static Connection getConn() {
        Connection con = conn.get();
        if (con == null) {
            try {
                Class.forName("com.mysql.jdbc.Driver");
                con = DriverManager.getConnection("url", "userName", "password");
                conn.set(con);
            } catch (ClassNotFoundException | SQLException e) {
                // ...
            }
        }
        return con;
    }

}

这样子,都是用同一个连接,但是每个连接都是新的,是同一个连接的副本。那么实现机制是如何的呢?

三、实现机制

1、每个Thread对象内部都维护了一个ThreadLocalMap这样一个ThreadLocal的Map,可以存放若干个ThreadLocal。

/* ThreadLocal values pertaining to this thread. This map is maintained
 * by the ThreadLocal class. */
ThreadLocal.ThreadLocalMap threadLocals = null;

2、当我们在调用get()方法的时候,先获取当前线程,然后获取到当前线程的ThreadLocalMap对象,如果非空,那么取出ThreadLocal的value,否则进行初始化,初始化就是将initialValue的值set到ThreadLocal中。
 

public T get() {
    Thread t = Thread.currentThread();
    ThreadLocalMap map = getMap(t);
    if (map != null) {
        ThreadLocalMap.Entry e = map.getEntry(this);
        if (e != null)
            return (T)e.value;
    }
    return setInitialValue();
}

3、当我们调用set()方法的时候,很常规,就是将值设置进ThreadLocal中。
4、总结:当我们调用get方法的时候,其实每个当前线程中都有一个ThreadLocal。每次获取或者设置都是对该ThreadLocal进行的操作,是与其他线程分开的。
5、应用场景:当很多线程需要多次使用同一个对象,并且需要该对象具有相同初始化值的时候最适合使用ThreadLocal。

事实上,从本质来讲,就是每个线程都维护了一个map,而这个map的key就是threadLocal,而值就是我们set的那个值,每次线程在get的时候,都从自己的变量中取值,既然从自己的变量中取值,那肯定就不存在线程安全问题,总体来讲,ThreadLocal这个变量的状态根本没有发生变化,他仅仅是充当一个key的角色,另外提供给每一个线程一个初始值。
 

第10篇:Agent + 爬虫 = 全自动数据采集专家 在企业级数据采集场景中,传统爬虫的痛点已经到了无法忽视的地步:而Agent + 爬虫的组合,就是这些痛点的终极解决方案。它的核心逻辑是:把爬虫从「人工写死的固定执行脚本」,升级为「能自主分析、自主决策、自主适配、自主修复的智能采集机器人」。我们在生产环境中做过对比测试:传统爬虫开发10个网站的采集脚本需要3人天,而Agent采集机器人只需要3分钟,页面改版后的修复成本从1人天降到了0,采集任务的成功率从62%提升到了95%以上。终端执行以下命令,安装基础依赖,与前9篇环境完全兼容: 二、核心能力拆解:Age 阅读详情

相关推荐

STM32移植u8g2库(HAL库)(硬件SPI)(sh1106_128x64)

STM32移植u8g2库(HAL库)(硬件SPI)(sh1106_128x64) MCU型号为STM32F103RCT6,OLED屏为中景园电子1.3寸屏,驱动芯片为sh1106,分辨率为128x64,MDK版本为V5.34。

Master_0_的博客 6272

解决多线程间共享变量线程安全问题的大杀器——ThreadLocal

上一期,讲到了关于线程死锁、用户进程、用户线程的相关知识,不记得的小伙伴可以看看:字节跳动面试官问我:你知道线程死锁吗?用户线程、守护线程的概念与区别了解吗? 这期,我们来聊一聊一个在Java并发编程中很重要的类:ThreadLocal 在多线程应用程序中,对共享变量进行读写的场景是很常见的。如果不使用一定的技术或方案,会引发各种线程安全的问题。常见解决线程安全的方式有synchronized、volatile等方式,但synchronized对性能的开销大,volatile不能保证原子性,所以这里介绍一个

YHJ 1万+

GD32 TIMER0 PWM输出死活没波形?别忘了这个关键配置(附完整代码)

本文详细解析了GD32 TIMER0 PWM输出无波形的常见问题,特别强调了高级定时器特有的主输出使能配置。通过完整的代码示例和调试技巧,帮助开发者快速解决PWM输出问题,适用于无刷电机控制等嵌入式应用场景。

weixin_30906185的博客 397

Java并发基础(21):多个线程读写同一共享变量是否存在并发问题?

1、

mingyuli的博客 4863

在工作台 LS-DYNA 中检索和变换反作用力分量

在结构仿真中,通常需要由施加的位移或速度边界条件产生的反作用力。此外,通常需要根据用户定义的坐标系解析反作用力分量。在本文中,详细介绍了在Workbench (WB) LS-DYNA 中,相对于用户定义的坐标系检索和变换反作用力分量的过程。

jkh920184196的博客 886

从URDF到Gazebo:一个完整的ROS2机械臂仿真项目实战与避坑指南

本文提供了一个完整的ROS2机械臂仿真项目实战指南,详细讲解了从URDF建模、ROS2 Control配置、MoveIt2集成到Gazebo仿真的全流程。文章重点分享了URDF惯性参数设置、Gazebo插件选择、MoveIt2配置修正等关键步骤的避坑经验,帮助开发者快速搭建可用的六轴机械臂仿真环境,实现从静态模型到物理仿真的跨越。

weixin_29279153的博客 275

JAVA之ThreadLocal的用途(多线程安全)

什么是ThreadLocal 多线程访问同一个共享变量的时候容易出现并发问题,特别是多个线程对一个变量进行写入的时候,为了保证线程安全,一般在访问共享变量的时候需要进行额外的同步措施才能保证线程安全性。 ThreadLocal是除了加锁这种同步方式之外的另一种保证多线程访问变量时的线程安全的方法;如果每个线程对变量的访问都是基于线程自己的变量这样就不会存在线程不安全问题。 在Java的多线程编程中,为保证多个线程对共享变量的安全访问,通常会使用synchronized来保证同一时刻只有一个线程对共享变量进行

★【World Of Moshow 郑锴】★ 1019

WebRTC TURN协议初识及turnserver实践

但是TURN协议对服务器有很高的依赖,服务器在带宽和集群上有很大的压力,所以TURN协议通常是当作ICE协议中的一部分来使用。ChannelData message不使用STUN头部,而使用一个4字节的头部,包含了一个称之为信道号的值(channel number),每一个使用中的信道号都与一个特定的peer绑定,即作为对等端地址的一个记号。该relay地址是个公网地址,可以看作是客户端A在公网上的一个代理,任何想要联系A的客户端,只要将数据发送到A的relay地址就可以了。

yinshipin007的博客 566

多个线程读写同一共享变量是否存在并发问题?

CPU缓存是为了加快处理器对内存的访问速度而引入的,它位于CPU内部,速度比主内存快得多。每个CPU核心都有自己的缓存,这意味着每个线程在不同的核心上运行时可能访问不同的缓存。在JMM中,每个线程都有自己的线程栈,线程间的共享变量存储在主内存中。的值时,这个修改可能会仅反映在该核心的缓存中,并不会立即更新主内存。由于线程具有各自的线程栈,它们可能会在不同的CPU核心上运行,并且每个核心有自己的CPU缓存。应该为0,但由于竞态条件,最终结果可能会是一个随机值,因为两个线程可能会同时读取和写入。

u011296842的专栏 645

ROS从入门到精通1-1:ROS核心架构、常用指令与计算图

本文介绍ROS的核心架构,各个文件、目录的用途、常用命令行工具、动态计算图原理。

FRIGIDWINTER的博客 6371

GIS常用符号化色带(超级色带)根据python制作

GIS自带的色带比较单一,今天分享一款色带,应用之后大家出图的时候可以选择更多的配色,符号化/点击色块/样式引用/将样式添加至列表即可。色带类型比较多,大家可以自己尝试下不同的风格。简单符号化一下,看看效果。以中国县级行政区划为例,

J_Giser的博客 2640

Java并发编程实践:解决多线程操作共享数据的问题

在实际开发中,需要根据具体的需求和场景选择合适的解决方案,并进行适当的测试和调优,以确保多线程程序的正确性和效率。然而,多线程编程也带来了一系列的挑战,其中最重要的一个问题就是多线程操作共享数据时可能出现的并发问题。Java提供了Atomic包下的一系列原子类,如AtomicInteger、AtomicLong等,通过使用这些原子类,可以保证对共享数据的操作是原子性的,避免了竞态条件和数据竞争的问题。为了解决多线程操作共享数据的问题,Java提供了多种并发编程的机制和工具,下面将介绍一些常用的解决方案。

C891106的博客 595

麒麟操作系统安装教程(保姆级)

本文介绍了如何在VM中安装麒麟操作系统,文章详细的介绍了麒麟操作系统按钻过步骤。

啊渊的专栏 1万+

threadLocal原理

一.ThreadLocal的作用   ThreadLocal提供的实际上就是一种线程隔离,不同的线程的变量归属不同的线程,线程之间不能想问访问各自的变量,当线程生命周期结束的时候,线程会被销毁。 二.ThreadLocal的原理 Thread类中有一个成员变量threadLocals: 这个ThreadLocalMap 是ThreadLocal类中一个静态内部类; ThreadLocal类中最主要的就是set 方法get方法; set方法 这个getMap(t); 传入一个Thr.

sam19911的博客 5531

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

ThreadLocal原理总结

一:ThreadLocal是什么? ThreadLocal,即线程本地变量。一个共享变量存进该容器相当于在线程内部拷贝了一个副本。ThreadLocal里面的变量都是存在当前线程的。当操作ThreadLocal里面的变量时,实际操作的是存在自己线程的那个变量副本,该变量副本对于每一个线程都是独立的,从而实现了变量的隔离性,保证了线程安全。 二:ThreadLocal保证线程变量隔离性的原理 每一个Thread线程都会拥有自己的一个成员变量ThreadLocalMap,该变量默认为空(实际是Thre

m0_57713282的博客 1万+

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

ThreadLocal原理详解——终于弄明白了ThreadLocal

目录 概述 API介绍 ThreadLocal的理解 ThreadLocal的原理分析 总结 概述 在java学习生涯中可能很多人都会听到ThreadLocal变量,从字面上理解ThreadLocal就是“线程局部变量”的意思。简单的说就是,一个ThreadLocal在一个线程中是共享的,在不同线程之间又是隔离的(每个线程都只能看到自己线程的值)。可能一开始把这句话放出来很难理解,那...

听得到微笑的博客 2万+

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

ThreadLocal原理以及用法详解

ThreadLocal叫做线程变量,意思是ThreadLocal中填充的变量属于当前线程,该变量对其他线程而言是隔离的,也就是说该变量是当前线程独有的变量。ThreadLocal为变量在每个线程中都创建了一个副本,那么每个线程可以访问自己内部的副本变量。 同一个 ThreadLocal 所包含的对象,在不同的 Thread 中有不同的副本。 ThreadLocal 变量通常被private static修饰。当一个线程结束时,它所使用的所有 ThreadLocal 相对的实例...

怪咖@的博客 1万+

ThreadLocal原理及使用场景

ThreadLocal ​ ThreadLocal意为线程本地变量,用于解决多线程并发时访问共享变量的问题。 ​ 所谓的共享变量指的是在堆中的实例、静态属性和数组;对于共享数据的访问受Java的内存模型(JMM)的控制,其模型如下: 【参考:《Java并发编程的艺术》P22】 每个线程都会有属于自己的本地内存,在堆(也就是上图的主内存)中的变量在被线程使用的时候会被复制一个副本线程的本地内存中,当线程修改了共享变量之后就会通过JMM管理控制写会到主内存中。 ​ 很明显,在多线程的场景下,当有多个线程对共享

weixin_44184990的博客 7万+

ThreadLocal的底层原理

一、ThreadLocal原理 ThreadLocal与线程同步机制不同,线程同步机制是多个线程共享同一个变量,对这个共享变量的修改,通过无锁或者有锁的机制保证线程的安全 而ThreadLocal是为每一个线程,创建一个只属于它自己的变量副本,线程可以改变自己所拥有的变量副本,而不会影响其他线程所对应的副本 简而言之,往ThreadLocal中填充的变量属于当前线程,该变量对其他线程而言是隔离的 一个线程使用自己的局部变量比使用全局变量方便且安全,因为局部变量只有线程自己能看见,不会影响其他线程 .

weixin_37841366的博客 4395

ThreadLocal原理、ThreadLocal的使用、ThreadLocal内存泄漏、ThreadLocal的坑

文章目录背景说明一:ThreadLocal的原理1.1 什么是ThreadLocal变量1.2 ThreadLocal实现原理1.3 ThreadLocalMap实现原理1.4 ThreadLocalMap结构图二:ThreadLocal的使用2.1 创建ThreadLocal工具类2.2 在拦截器/过滤器中通过用户token获取登录信息,并与当前线程绑定2.3 业务处理时获取用户信息2.4 当前请求结束时,销毁ThreadLocal变量三:ThreadLocal的坑、ThreadLocal内存泄漏3.1

weixin_49114503的博客 8911

ThreadLocal底层原理

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

许苑向上 1831

ThreadLocal的原理

在多线程环境下,会使用ThreadLocal来保存变量,这样即使在多线程的环境下,也能够以线程安全的方式来使用变量。 1、在多线程环境中,使用ThreadLocal来保存变量时,变量是存在什么地方?      简要来说,使用ThreadLocal来保存相关变量时,这个变量是存在当前使用ThreadLocal对象的这个线程中的,也就是当前线程,即Thread.curren

Lynn 2480

ThreadLocal 的原理及用法

一、ThreadLocal原理 简单说 ThreadLocal 就是一种以空间换时间的做法,在每个 Thread 里面维护了一个以开放定址法实现的ThreadLocal.ThreadLocalMap,把数据进行隔离,数据不共享,自然就没有线程安全方面的问题了。 JDK1.2 就提供了java.lang.ThreadLocal。ThreadLocal 为解决多线程程序的并发问题提供了一种新的思路。使用这个工具类可以很简洁地编写出优美的多线程程序,ThreadLocal 并不是一个 Thread,而是 Thre

ChineseSoftware的博客 1576

ThreadLocal原理浅析

ThreadLocal即线程局部变量的意思!所以什么是线程局部变量?这玩意有什么鸟用?是不是面试被问到了说不出个一二三?今天就来扒一扒这货的源码,从根本上了解这货是干啥的。 其实研究下来他的源码实现,其实也没想象的那么复杂,其最主要有以下几点: 1、每一个Thread对象都有一个ThradLocalMap实例 dfadfadf 参考资料: ThreadLocal源码分析 ...

菜鸟博客 1908

ThreadLocal原理解析

当我们在使用多个线程访问一个共享变量的时候特别容易带来数据安全问题,尤其是我们在对一个共享变量写操作的时候,我们通常的解决方案是加锁,使对该共享变量的操作串行化,那么有没有一种方式可以做到,创建一个变量,每个线程对其访问的时候访问的是自己线程变量呢?使用ThreadLocal就可以实现。 ThreadLocal它提供了一个本地线程变量,通俗的讲就是你创建了一个ThreadLocal变量,线程a在给...

猿上生活 1476

ThreadLocal的应用及原理

此类提供线程局部变量。这些变量与其正常对应变量的不同之处在于,每个访问一个(通过其get或set方法)的线程都有自己的、独立初始化的变量副本。ThreadLocal实例通常是类中的私有静态字段,这些字段希望将状态与线程(例如,用户ID或事务ID)相关联。例如,下面的类生成每个线程本地的唯一标识符。线程的id在第一次调用ThreadId.get()时被分配,并且在随后的调用中保持不变。

深圳市多克创新科技有限公司 942
上一篇: 源码分析常见问题
下一篇: Java NIO:浅析I/O模型
HY_Chan
博客等级 码龄10年 54粉丝 60原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值