ThreadLocal介绍

Ansys EMC Plus:用于仿真屏蔽效果的一键式工作流程 在 EMA3D 选项卡下,单击 Shielding Effectiveness 按钮下方的箭头以访问设置并使用所需数量的分割数启动工作流程,这些分割数定义了网格大小。在此示例中,设置了 35 个分段,提供了良好的 FDTD 网格,同时保持了较短的仿真运行时间。接下来,选择默认的平面波源文件,然后选择所需的分析方向。您还可以查看和调整仿真树中的仿真参数,包括定义最低和最高频率值的解域、入射平面波的极化以及探针设置。您可以控制屏蔽效果图设置,并以线性比例显示结果。仿真完成后,软件将绘制与频率相关的屏蔽效果图。 阅读详情


ThreadLocal和Synchonized都用于解决多线程并发访问,但实现机制却有着本质区别。Synchronized是利用加锁的方式,允许某个代码块只能被一个线程所访问。而ThreadLocal则是通过为每个线程都提供变量的副本,这样每个线程在访问时,实际上访问的是属于自身的变量,而不是同一个变量,这样就隔离了多个线程对数据的共享。

ThreadLocal的使用

ThreadLocal类常用的方法有4个,分别是:

  • void set (T var1) // 设置当前线程的线程局部变量的值。
  • void T get () // 返回当前线程所对应的线程局部变量。
  • void remove () // 将当前线程的局部变量的值给删除,目的是为了减少内存的使用,需要指出的是,当线程结束后,对应该线程的局部变量将自动被垃圾回收,所以显示调用该方法去清除线程的局部变量不是必须的操作,但它可以加快内存回收的速度。
  • void initialValue() // 返回该线程局部变量的初始值,该方法是一个protected方法,显然是为了让子类覆盖而设计的。这个方法是一个延迟调用的方法,在线程第一次set(T var1) 或者get() 才执行,并且仅执行1次。ThreadLocal中的缺省实现直接返回一个null。

ThreadLcoal实现原理

在这里插入图片描述
每个Thread持有一个ThreadLocalMap对象,ThreadLocalMap中存在Entry数据结构,Entry类似HashMap,Entry中的key是ThreadLocal,value则是Object。

static class Entry extends WeakReference<ThreadLocal<?>> {
            /** The value associated with this ThreadLocal. */
            Object value;

            Entry(ThreadLocal<?> k, Object v) {
                super(k);
                value = v;
            }
        }

这上图,我们可以知道,每个Thread都有自己的ThreadLocalMap来访问自己的变量,也就不存在访问冲突的问题了。在ThreadLocal的get() 或者是set(T var1) 方法中,我们首先是通过Thread.currentThread() 来获得当前线程持有的ThreadLocalMap对象,然后再进行赋值或者是取值操作。

ThreadLocal的内存泄露

在这里插入图片描述

ThreadLocal仅仅是一个管理类而已,真正的对象存储再Thread里。ThreadLocal会被当做ThreadLocalMap中Entry的key,且Thread持有ThreadLocalMap,进而简介持有ThreadLocal, 正常情况下这就有可能出现内存泄漏的风险(Thread长周期, ThreadLocal短周期),对此ThreadLocalMap中的Entry中的采用了上图所示的预防。
Entry中的key使用了弱引用, 再者,我们正常使用ThreadLocal的时候,一般将其设置为static, 而static又是全局的,就不会存在ThreadLocal泄漏的说法了。
但是:Entry中的key使用了弱引用,而其value(我们存储的对象)并没有使用弱引用。当JVM进行垃圾回收时,就会把key给回收掉,此时key = null, 而value并没有被回收。
结论:ThreadLocal变量本身不存在内存泄漏问题,但是value有内存泄露的风险。
解决办法 使用完毕记得调用ThreadLocal.remove() 移除key和value。(remove()方法的核心在于执行了expungeStaleEntry(int staleSlot) 方法,它会清除在key = null 的情况下的value值,在set(T var1)或者 get() 方法时也会执行expungeStaleEntry(int staleSlot) 方法,但不是每次都会执行)

错误使用ThreadLocal出现 线程不安全的情况

首先运行如下代码:

public class ThreadLocalUnsafe implements Runnable {

    public static Number number = new Number(0);

    public void run() {
        //每个线程计数加一
        number.setNum(number.getNum()+1);
      //将其存储到ThreadLocal中
        value.set(number);
        SleepTools.ms(2);
        //输出num值
        System.out.println(Thread.currentThread().getName()+"="+value.get().getNum());
    }

    public static ThreadLocal<Number> value = new ThreadLocal<Number>() {
    };

    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            new Thread(new ThreadLocalUnsafe()).start();
        }
    }

    private static class Number {
        public Number(int num) {
            this.num = num;
        }

        private int num;

        public int getNum() {
            return num;
        }

        public void setNum(int num) {
            this.num = num;
        }

        @Override
        public String toString() {
            return "Number [num=" + num + "]";
        }
    }

}

出现如下结果:
在这里插入图片描述
这里每个线程都输出5的原因在于ThreadLocalMap中保存的其实一个对象的引用,这样的话,当有其它线程对这个引用指向的对象实例做修改时,其实也影响了所有的线程持有的对象引用所指向的同一个对象实例。这也就解释了上面5个线程出现同样的结果:5个线程保存的是同一个Number对象的引用,在线程休眠的时候,其它线程将num变量做了修改,而修改的对象Number的实例是同一份,因此它们最终的输出结果是一样的。
解决办法: 每个线程中的ThreadLocal都应该持有一个新的Number对象,可以将去掉修饰Number的static 关键字,或者重写给ThreadLocal的initialValue()方法,给定一个初始值。

ThreadLocal在Android中的使用场景

Handler创建的时候会采用当前线程的Looper来构造消息循环系统,那么Handler是如何获取得到当前线程的Looper呢?这就要使用ThreadLocal了, ThreadLocal可以在不同的线程之中互不干扰地存储并提供数据,通过ThreadLocal可以轻松获取每个线程地Looper。需要注意的是,线程默认是没有Looper的,使用Handler就必须为线程创建Looper,大家经常提到的主线程(UI线程),它就是ActivityThread, ActivityThread被创建的时候就会初始化Looper,这也就是主线程默认可以使用Handler的原因。
一般来说,当某些数据以线程为作用域并且不同线程具有不同的数据副本的时候,就可以考虑使用ThreadLocal,比如Handler,它需要获取当前线程的Looper,显然Looper的作用域就是线程并且不同的线程具有不同的Looper,这个时候通过ThreadLocal就可以轻松实现Looper在线程的存取。

STM32CubeMX配置FSMC驱动外部SRAM全流程详解 FSMC(灵活静态存储控制器)是STM32实现高速并行外部存储扩展的核心外设,其本质是将片外SRAM地址空间映射为CPU可直接读写的内存区域。原理上依赖于精确的时序寄存器配置(如BTRx)、GPIO复用功能启用及AHB3总线时钟同步机制,技术价值在于免DMA搬运的零拷贝访问能力与确定性低延迟。典型应用场景包括工业HMI缓存、医疗设备实时数据采集、嵌入式图形加速等对带宽和确定性要求严苛的系统。本文围绕STM32F407ZG平台,结合STM32CubeMX工程化配置、硬件信号完整性设计与HAL库底层映射逻辑,系 阅读详情

相关推荐

AI 代码生成工具的质量评估体系

基础需求层包括响应速度(Response Time)和界面友好性(UI Friendliness),期望需求层涵盖智能提示(Smart Suggestions)和个性化配置(Personalization),兴奋需求层则涉及多模态交互(Multimodal Interaction)和代码进化(Code Evolution)。在金融领域,代码审计合规性(Compliance Audit)权重应提升至40%,而在Web开发中,API兼容性(API Compatibility)的权重需达到35%。

2503_92418637的博客 3372

ThreadLocal 实战应用

在 Spring 项目中 Dao 层中装配的 Connection 肯定是线程安全的,其解决方案就是采用 ThreadLocal 方法,当每个请求线程使用 Connection 的时候, 都会从 ThreadLocal 获取一次,如果为 null,说明没有进行过数据库连接,连接后存入 ThreadLocal 中,如此一来,每一个请求线程都保存有一份 自己的 Connection。每个线程的 ThreadLocalMap 是属于线程自己的,ThreadLocalMap 中维护的值也是属于线程自己的。

Stone.鱼儿的博客 1480

matlab电偶极子源码,电偶极子的MATLAB场模拟

电偶极子周围电场电势分布的MATLAB三维模拟Matlab可以用于模拟四维场的效果,本文以电偶极子的电场和电势场为例展示MATLAB在该方面领域的应用。摘要电偶极子由一个正电荷和一个负电荷组成,其电场和空间电势分布与单电荷相比具有一些重要的特性。本文将给出电场和电势场的近似表达式。这两个量的精确表达式是复杂的,不太常用,因此 MATLAB 被采用来操作精确值和绘制三维分布的远区域, 近区域和一侧区...

weixin_35135480的博客 3150

对ThreadLocal的理解【源码分析+应用举例】

ThreadLocal可以使每个线程保存自己的一些私有数据,起到线程隔离的作用。打个比方,可以将其比喻成大型超市里的公共储物柜,每个人都可以使用,但是储物柜又分为好多小箱子来保证每个顾客有属于自己的存储空间,只能存取自己的物品。

Mr_Liu946的博客 1480

TYPE-C PD协议实战:如何用LDR6028芯片实现边充电边OTG(附完整电路设计)

本文详细解析了如何利用LDR6028芯片实现TYPE-C接口在PD协议下的边充电边OTG功能。通过剖析PD协议双角色协商的核心挑战,提供了完整的硬件电路设计要点,包括Type-C接口配置、电源路径管理及系统框架,并附有调试实战指南,助力开发者构建稳定可靠的一线多用解决方案。

c6d7e8f9g的博客 1126

AutoSAR EcuM系列01- EcuM模块的功能概述和变体类型

在【ECU的软硬件架构】文章中我们了解ECU的功能和组成,那么ECU具体是怎么启动的呢?我们知道,AutoSAR标准架构有三层,即APPL应用层、RTE层和BSW层。而这些层又被进一步划分为更多单独的组件,如BSW层可能有80多个组件。在ECU启动时,这些组件必须相互交互,有时也必须以某种顺序交互。这些组件的启动顺序由ECU管理器模块或EcuM处理。EcuM负责整个ECU的初始化和去初始化,包括对一些系统模块如。......

1766

huTool--工具类常用方法

转载链接 https://www.jianshu.com/p/fa5ef558b286 官方文档 https://www.hutool.cn/

liucy007的博客 733

数据科学助力大数据领域的航空安全分析

随着航空业的快速发展,航班数量不断增加,航空安全问题日益受到关注。大数据时代的到来,使得航空领域积累了大量的数据,包括飞行数据、维护数据、气象数据等。本文章的目的在于探讨如何运用数据科学的方法和技术,对这些大数据进行分析,以提高航空安全水平。范围涵盖了从数据收集、预处理到数据分析、模型构建和应用的整个流程。本文将按照以下结构进行组织:首先介绍数据科学和航空安全分析的核心概念以及它们之间的联系;接着阐述核心算法原理和具体操作步骤,并使用Python源代码进行详细说明;

软件工程实践的博客 1292

用ThreadLocal作为memcache的事务解决方案遇到的问题

ThreadLocal 是java官方提供的一套基于本地变量的解决线程安全问题的解决方案,他是对于每一个线程提供一个只有本线程可见的变量副本,存放于以本线程对象为key的map中去。ThreadLocal接口简介:   ThreadLocal的接口方法   ThreadLocal类接口很简单,只有4个方法,我们先来了解一下:   void set(Object value)   设置当前线...

weixin_30518397的博客 154

第4章 部署负载均衡 Keepalived + HAProxy

本章在所有 Master 节点部署 Keepalived + HAProxy,为 kube-apiserver 提供高可用入口。Keepalived 实现 VIP(192.168.3.59)漂移,HAProxy 轮询转发请求至三个 Master 的 6443 端口(监听 6444 避免冲突)。健康检查脚本连续 5 次失败则停止 Keepalived,触发 VIP 自动切换。本章还包含配置详解、日常运维和问题排查。

幸福街--linux技术分享 120

【LaTex】3.5 数据分析

简述了LaTex柱状图、饼图、折线图的画法。

你的指尖有改变世界的力量 5887

分析Threadlocal内部实现原理,并解决Threadlocal的ThreadLocalMap的hash冲突与内存泄露

前言 ThreadLocal 的经典使用场景是数据库连接、session 管理、多线程等…… 比如在Spring中,发挥着巨大的作用,在管理Request作用域中的Bean、事务管理、任务调度、AOP等模块都不同程度使用了ThreadLocal 。 Spring中绝大部分Bean,都可以声明成Singleton作用域,采用ThreadLocal进行封装,因此有状态的Bean,就能够以singleton的方式,在多线程中正常工作。 知道Threadlocal怎么用,但是不知道为什么要这样用?底层原理是.

阿啄debugIT 2212

【OAG vs RAG】OAG工程实战(下):权限治理与多模型协同

本文摘要(149字): OAG工程体系的核心挑战在于权限治理与多模型协同。文章深入探讨OMA(对象管理权限)系统,实现细粒度访问控制:通过对象级权限管理行级安全,属性级权限控制敏感字段脱敏,确保AI Agent权限不越界。系统采用三层次防护:对象策略控制记录可见性,属性策略处理字段级脱敏,动作策略限制操作范围。权限验证贯穿Agent执行全流程,结合多模型交叉验证机制,构建企业级AI安全防线。这些设计使OAG系统从技术演示升级为生产可用的企业解决方案。

求知若渴、虚心若愚 104

ThreadLocal介绍及使用

ThreadLocal可以使每个线程保存自己的一些私有数据,起到线程隔离的作用。打个比方,可以将其比喻成大型超市里的公共储物柜,每个人都可以使用,但是储物柜又分为好多小箱子来保证每个顾客有属于自己的存储空间,只能存取自己的物品。 下面来看看ThreadLocal的使用。 1.ThreadLocal.get()和Thr...

lifes_java的博客 138

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

ThreadLocal 介绍

ThreadLocal 的作用是:提供线程内的局部变量,不同的线程之间不会相互干扰,这种变量在线程的生命周期内起作用,减少同一个线程内多个函数或组件之间一些公共变量传递的复杂度。线程并发:在多线程并发的场景下传递数据:我们可以通过 ThreadLocal 在同一线程,不同组件中传递公共变量线程隔离:每个线程的变量都是独立的,不会互相影响常用方法| 方法声明 | 描述 |

weixin_46840095的博客 867

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

ThreadLocal--ThreadLocal介绍

摘要:ThreadLocal是Java提供的线程本地变量机制,每个线程独立维护变量副本,用于上下文传递、线程安全对象存储等场景。其核心实现依赖ThreadLocalMap,采用弱引用key防止内存泄漏。使用时需注意:1)线程池场景必须手动remove();2)子线程继承需用InheritableThreadLocal。典型应用包括用户会话管理、SimpleDateFormat线程安全封装等。关键点在于理解ThreadLocalMap的弱引用机制和及时清理,避免内存泄漏风险。(148字)

你我约定有三的博客 1030

ThreadLocal介绍和使用

ThreadLocal介绍和使用

chengbo_eva的博客 2033

ThreadLocal 简单介绍

ThreadLocal 简单介绍

吴川华仔的博客 550

threadLocal介绍

早在JDK 1.2 的版本中就提供java.lang.ThreadLocal ,ThreadLocal 为解决多线程程序的并发问题提供了一种新的思路。使用这个工具类可以很简洁地编写出优美的多线程程序。 ThreadLocal 很容易让人望文生义,想当然地认为是一个“ 本地线程” 。其实,ThreadLocal 并不是一个Thread ,而是Thread 的局部变量,也许把它...

Turn myself into a beast. 162

Android开发——ThreadLocal功能介绍

ThreadLocal适用于某些数据以线程为作用域并且不同线程具有不同数据副本的场景。 比如对于Handler来说,它需要获取当前线程的Looper,很显然Looper的作用域就是线程并且不同线程具有不同的Looper,这个时候通过ThreadLocal就可以轻松实现Looper在线程中的存取。 ThreadLocal的另一个使用场景是复杂逻辑下的对象传递。 比如监听器的传递,有时一个...

关于Android开发的一些技术点总结 ╮( ̄▽ ̄”)╭ 1万+

介绍threadlocal

线程复用:在使用线程池时,线程可能会被复用,这可能会导致 ThreadLocal 的值被错误地共享。- 数据隔离:通过 ThreadLocal 存储的数据是线程隔离的,即每个线程只能访问和修改自己的数据副本。- 日志记录:每个线程可能会产生不同的日志信息,使用 ThreadLocal 可以避免日志信息的混淆。在这个示例中,每个线程都会获取和更新自己的 ThreadLocal 变量副本,而不会影响其他线程的值。- 线程局部变量:每个线程可以访问自己的 ThreadLocal 变量,而不会与其他线程冲突。

ruky36的专栏 480
上一篇: JNI简单使用
下一篇: 自定义View的一些注意点
OneLinee
博客等级 码龄10年 11粉丝 41原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值