你知道为什么局部变量是线程安全的吗?

Java并发编程 | 局部变量为什么是线程安全的 前言 本篇文章说一个比较简单的东西,就是局部变量为什么是线程安全的,对于熟悉JVM的开发者来说这个问题可以忽略不计。所以本篇文章作为知识回顾和扩展。 正文 本系列文章一直说的都是并发编程,即多个线程同时访问共享变量的时候,会导致并发问题,那么在Java语言里,是不是所有变量都会是共享变量呢 局部变量 比如我们看下面这个fibonacci()方法,会根据传入的参数n,返回1到n的斐波那契数列,斐波那契数列数列类似这样:1、1、2、3、5、8...,即第一项和第二项是1,第三项开始,每一项等于前俩项之 阅读详情

前言

多个线程同时访问共享变量时,会导致并发问题。那么,如果将变量放在方法内部,是不是还会存在并发问题呢?如果不存在并发问题,那么为什么不会存在并发问题呢?

需要更多Java知识点和面试题的朋友可以点一点下方链接免费领取

链接:1103806531暗号:优快云

在这里插入图片描述

著名的斐波那契数列

记得上学的时候,我们都会遇到这样一种题目,打印斐波那契数列。斐波那契数列是这样的一个数列:1、1、2、3、5、8、13、21、34…,也就是说第1项和第2项是1,从第3项开始,每一项都等于前2项之和。我们可以使用下面的代码来生成斐波那契数列。

//生成斐波那契数列
public int[] fibonacci(int n){
    //存放结果的数组
    int[] result = new int[n];
    //数组的第1项和第2项为1
    result[0] = result[1] = 1;
    //计算第3项到第n项
    for(int i = 2; i < n; i++){
        result[i] = result[i-2] + result[i-1];
    }
    return result;
}

假设此时有很多个线程同时调用fibonacci()方法来生成斐波那契数列,对于方法中的局部变量result,会不会存在线程安全的问题呢?答案是:不会!!

接下来,我们就深入分析下为什么局部变量不会存在线程安全的问题!

方法是如何被执行的?

我们以下面的三行代码为例。

int x = 5;
int[] y = fibonacci(x);
int[] z = y;

当我们调用fibonacci(x)时,CPU要先找到fibonacci()方法的地址,然后跳转到这个地址去执行代码,执行完毕后,需要返回并找到调用方法的下一条语句的地址,也就是int[] z = y的地址,再跳到这个地址去执行。我们可以将这个过程简化成下图所示。

在这里插入图片描述

这里需要注意的是:CPU会通过堆栈寄存器找到调用方法的参数和返回地址。

例如,有三个方法A、B、C,调用关系为A调用B,B调用C。在运行时,会构建出相应的调用栈,我们可以用下图简单的表示这个调用栈。

在这里插入图片描述
每个方法在调用栈里都会有自己独立的栈帧,每个栈帧里都有对应方法需要的参数和返回地址。当调用方法时,会创建新的栈帧,并压入调用栈;当方法返回时,对应的栈帧就会被自动弹出。

我们可以这样说:栈帧是在调用方法时创建,方法返回时“消亡”。

局部变量存放在哪里?

局部变量的作用域在方法内部,当方法执行完,局部变量也就没用了。可以这么说,方法返回时,局部变量也就“消亡”了。此时,我们会联想到调用栈的栈帧。没错,局部变量就是存放在调用栈里的。此时,我们可以将方法的调用栈用下图表示。

在这里插入图片描述

很多人都知道,局部变量会存放在栈里。如果一个变量需要跨越方法的边界,就必须创建在堆里。

调用栈与线程

两个线程就可以同时用不同的参数调用相同的方法。那么问题来了,调用栈和线程之间是什么关系呢?答案是:每个线程都有自己独立的调用栈。我们可以使用下图来简单的表示这种关系。

在这里插入图片描述
此时,我们在看下文中开头的问题:Java方法内部的局部变量是否存在并发问题?答案是不存在并发问题!因为每个线程都有自己的调用栈,局部变量保存在线程各自的调用栈里,不会共享,自然也就不存在并发问题。

线程封闭

方法里的局部变量,因为不会和其他线程共享,所以不会存在并发问题。这种解决问题的技术也叫做线程封闭。官方的解释为:仅在单线程内访问数据。由于不存在共享,所以即使不设置同步,也不会出现并发问题!

最后

我这边也整理了一份 架构师全套视频教程和关于java的系统化资料,包括java核心知识点、面试专题和20年最新的互联网真题、电子书等都有。有需要的朋友可以点一点下方链接免费领取!

链接:1103806531暗号:优快云

在这里插入图片描述

在这里插入图片描述

11 | Java线程(下):为什么局部变量是线程安全的? 我们一遍一遍重复再重复地讲到,多个线程同时访问共享变量的时候,会导致并发问题。那在 Java 语言里,是不是所有变量都是共享变量呢?工作中我发现不少同学会给方法里面的局部变量设置同步,显然这些同学并没有把共享变量搞清楚。那 Java 方法里面的局部变量是否存在并发问题呢?下面我们就先结合一个例子剖析下这个问题。 阅读详情

相关推荐

(OpenCV)图像目标尺寸检测

  本文翻译自pyimagesearch技术博客上的一篇文章,《Measuring size of objects in an image with OpenCV》,原文作者:Adrian Rosebrock 。 https://www.pyimagesearch.com/2016/03/28/measuring-size-of-objects-in-an-image-with-opencv...

明柳梦少的博客 7万+

【高并发】终于弄懂为什么局部变量是线程安全的了!!

写在前面小说网 www.198200.com 相信很多小伙伴都知道局部变量是线程安全的,那你知道为什么局部变量是线程安全的吗? 前言 多个线程同时访问共享变量时,会导致并发问题。那么,如果将变量放在方法内部,是不是还会存在并发问题呢?如果不存在并发问题,那么为什么不会存在并发问题呢? 著名的斐波那契数列 记得上学的时候,我们都会遇到这样一种题目,打印斐波那契数列。斐波那契数列是这样的...

keocce的博客 959

cadence Virtuoso ADE原理图库中的VCVS(压控电压源)使用

Symbol: vcvs (Voltage Controlled Voltage Source) Vop−Von=egain⋅(Vip−Vin)V_{op}-V_{on}=egain\cdot(V_{ip}-V_{in})Vop​−Von​=egain⋅(Vip​−Vin​) 所以可以得出 ⟹Vop=egain⋅(Vip−Vin)+Von\Longrightarrow V_{op}=egain\cdot(V_{ip}-V_{in})+V_{on}⟹Vop​=egain⋅(Vip​−Vin​)+Von​ 使

大学生视野 2万+

关于变量的线程安全问题

Hashtable中,单独的get和put都是线程安全的,但组合起来使用,则不保证线程安全,因为get和put之间不是原子的,可能发生上下文切换。如果多线程下使用集合,除了上面的Vector和HashTable,还可以使用Collections的下列方法,把普通的集合类变成线程安全的集合类。String、Integer类都是不可变类,因此它们的方法都是线程安全的,修改内容后会返回一个新的对象,而不会修改原始对象的值。需要线程安全时使用左边的,不需要时使用右边的,同一行的用法是一样的。

m0_62609939的博客 1505

非易失存储器读写

24C256、IIC_SCL、IIC_SDA

CT_1104的专栏 2987

PCIe网卡驱动实现分析(三)--- cache一致性

在现代处理器系统中,CPU的主频远高于主存读写速度,主存的读写速度成为程序执行效率的瓶颈;为了解决这个问题,在CPU和主存之间引入了Cache存储器,基于程序执行的局部性原理,在程序执行时,将正在使用的数据从主存拷贝一份到Cache,这样CPU就可以直接从Cache读写数据以改善主存读写速度慢的问题;

a935854743的博客 1779

三、线程安全

wait()、notify()、 notifyAll() 方法都是属于Object 对象的方法,需要获取此对象的锁 之后才能够使用wait() 对象调用wait() 方法之后,线程会 Owner中释放锁,然后进入WaitSet中等待唤醒wait( time ) 对象调用带参数的wait()方法之后,线程会 Owner中释放锁,然后进入WaitSet中等待 指定时间,然后如果期间没有被唤醒,指定之间之后就会自动唤醒,然后进入EntryList再次尝试获取锁,竞争锁。

yuigjjhgjh的博客 1554

【硬核指南/MI50 32G/Ubuntu】从零部署大模型:MI50显卡Ubuntu系统驱动安装与避坑全记录

本文详细记录了在Ubuntu系统上为AMD MI50显卡安装驱动并部署大模型的完整流程,包括硬件兼容性检查、BIOS关键设置、系统安装优化、ROCm驱动安装及常见问题解决方案。特别针对MI50显卡在X99平台上的特殊配置需求提供了实用技巧,帮助用户避免常见陷阱,提升大模型训练效率。

weixin_42520909的博客 813

局部变量是线程安全的,原因是什么?

局部变量的线程安全性原因是因为每个线程都有自己独立的线程栈空间,不同线程之间不会共享局部变量。需要注意多线程同时访问同一个引用类型的局部变量时可能出现的线程竞争问题,需要加锁保证线程安全。作者:Lion Long链接:https://www.zhihu.com/question/601406551/answer/3033562577来源:知乎。

nihao_2014的博客 451

【Docker】搭建一个媒体服务器插件后端API服务 - MetaTube

本教程基于群晖的NAS设备DS423+的docker功能进行搭建,DSM版为 7.2.1-69057 Update 5。MetaTube是一个媒体服务器插件,主要用于Emby和Jellyfin媒体服务器。它的主要功能是从互联网上抓取内容并响应 JSON 数据,然后通过预安装的 MetaTube 插件请求服务器并下载相应的元数据,以与 Jellyfin/Emby 服务器配合使用。使用 MetaTube 的步骤大致如下:部署后端:首先,需要部署一个名为​ 的后端 API 服务器来抓取内容。

小小笔记大大用处 1万+

【OpenClaw企业级智能体实战】第16篇:电商“龙虾”掘金记:用OpenClaw实现小红书/抖音/淘宝全自动矩阵运营(2026实测版)

2026年,OpenClaw(小龙虾)已成为电商运营的核心效率工具——从公众号文案3分钟生成到TikTok爆款视频1小时复刻,从多平台内容同步到自动比价加购,彻底重构了电商运营的工作模式。本文基于真实商业案例(元岳科技、TikTok跨境卖家、淘宝MCP工具),系统拆解电商智能体的落地路径:先详解OpenClaw在电商场景的核心原理与变现模式(代部署、模板售卖、轻定制、内容套利),再提供阿里云/本地双部署方案,完整实现小红书/抖音/淘宝的自动化运营(热点抓取、内容生成、多平台分发、数据分析)。

专注于人工智能、软件开发、工控自动化、工厂数字化及智能化等领域,希望和大家共同进步! 2300

Java并发 -- 局部变量

int a = 7; int[] b = fibonacci(a); int[] c = b; 当调用fibonacci(a)的时候,CPU需要先找到方法fibonacci()的地址,然后跳转到这个地址去执行代码 最后CPU执行完fibonacci()方法之后,要能够返回,需要找到调用fibonacci()方法的下一条语句的地址 即int[] c = b;然后跳转到这个地址去执行 ##栈寄...

Java_No2的博客 573

基于YOLOv26的智能农业无人机巡检系统

本文提出了一种基于YOLOv26的智能农业无人机巡检系统。系统采用模块化设计,包含数据采集、预处理、目标检测、图像拼接、分析决策和部署控制六大核心模块。无人机搭载多光谱相机、RGB相机和热红外相机进行农田数据采集,通过YOLOv26实现作物病虫害、杂草及灌溉设备的检测。系统采用PyTorch、OpenCV等技术栈,支持无人机自动路径规划和多传感器数据采集,并包含数据增强和预处理功能。该系统可有效提升农业巡检效率,为精准农业提供智能化解决方案。

一键难忘的博客 810

为什么局部变量线程安全

为什么局部变量线程安全 我们知道方法内部定义的变量属于局部变量,而局部变量的作用域仅仅存在一个方法的内部,不能被外部所引用,那这到底是为什么呢? 场景引入 假如存在方法计算斐波那契数列,什么是斐波那契数列呢,就是第一项和第二项都是1,从第三项开始,每一项都是前两项的和形如:1、1、2、3、5、8、13…那么多线程下变量r是否存在线程安全的问题呢? public class Test { public int[] fibonacci(int n){ int[] r = new int

zzf1233的博客 4874

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

为什么局部变量是线程安全的?

我们一遍一遍重复再重复地讲到,多个线程同时访问共享变量的时候,会导致并发问题。那在Java语言里,是不是所有变量都是共享变量呢?工作中我发现不少同学会给方法里面的局部变量设置同步,显然这些同学并没有把共享变量搞清楚。那Java方法里面的局部变量是否存在并发问题呢?下面我们就先结合一个例子剖析下这个问题。

qq_33240556的博客 1025

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

【高并发】面试官问我:为什么局部变量是线程安全的?

终于弄懂为啥局部变量是线程安全的了!!

冰河的专栏 1076

10 - 为什么局部变量是线程安全的

为什么局部变量是线程安全的1. 方法是如何被执行的2. 局部变量存哪里3. 调用栈与线程4. 线程封闭5. 思考   我们一遍一遍重复再重复地讲到,多个线程同时访问共享变量的时候,会导致并发问题。那在 Java 语言里,是不是所有变量都是共享变量呢?工作中我发现不少同学会给方法里面的局部变量设置同步,显然这些同学并没有把共享变量搞清楚。那 Java 方法里面的局部变量是否存在并发问题呢?下面我们就先结合一个例子剖析下这个问题。      比如,下面代码里的 fibonacci() 这个方法,会根据传入的参数

pizicai007的博客 533

局部变量是线程安全的,原因是什么

很多小伙伴都知道局部变量是线程安全的,那你知道为什么局部变量是线程安全的吗?

华为云官方博客 1542

局部变量是否线程安全

了解过JVM的都知道,堆和方法区(JDK1.8后叫元空间)是线程共享的 虚拟机栈、程序计数器(PC寄存器)和本地方法栈是线程私有的 虚拟机栈里面存的是一个一个的栈帧,这里的栈帧你也可以理解为此时正在运行的方法,如果此方法调用其他方法的话,在虚拟机栈中就形成了一个个栈帧堆叠的形态,相信读到这里你已经对虚拟机栈的样子有了感觉 接着,我们讨论栈帧(方法 栈帧有五个部分组成 局部 变量表 操作数栈 动态链接【方法的符号引用,在这里我们可以讨论虚方法(在运行时确定方法,把符号引用转为直接引用)和非虚方

qq_42114504的博客 2199

局部变量为什么是线程安全的

我们一遍一遍重复讲到,多个线程同时访问共享变量时,会导致并发问题,那在Java 语言里,是不是所有的变量都是共享变量呢?工作中我发现不少同学会给方法里的局部变量设置同步,显然这些同学并没有把共享变量说清楚。那么Java 方法里的局部变量是否存在并发问题呢? 其实很多人都知道局部变量是不存在数据竞争的,至于原因嘛,就说不清楚了。 那它背后的原因到底是什么样的呢?要弄清楚这个,你需要一点编译原理的知识,你知道在CPU 层面,是没有方法概念的。CPU 的眼里只有一条条的指令。编译程序,负责把高级语言里的方法转

qq_19072921的博客 281

Day831.局部变量为什么是线程安全的 -Java 并发编程实战

调用栈是一个通用的计算机概念,所有的编程语言都会涉及到,Java 调用栈相关的知识,并没有花费很大的力气去深究,但是靠着那点 C 语言的知识,稍微思考一下,基本上也就推断出来了。递归调用太深,可能导致栈溢出。原因是什么?有哪些解决方案呢?栈溢出原因:因为每调用一个方法就会在栈上创建一个栈帧,方法调用结束后就会弹出该栈帧,而栈的大小不是无限的,所以递归调用次数过多的话就会导致栈溢出。而递归调用的特点是每递归一次,就要创建一个新的栈帧,而且还要保留之前的环境(栈帧),直到遇到结束条件。

阿昌爱Java 778

面试官问我:为啥局部变量是线程安全的?面试知识又上涨了真香!

面试官问我:为啥局部变量是线程安全的?面试知识又上涨了真香! 相信很多小伙伴都知道局部变量是线程安全的,那你知道为什么局部变量是线程安全的吗? 多个线程同时访问共享变量时,会导致并发问题。那么,如果将变量放在方法内部,是不是还会存在并发问题呢?如果不存在并发问题,那么为什么不会存在并发问题呢? 最新2020整理收集的一线互联网公司面试真题(都整理成文档),有很多干货,包含netty,spring,线程,spring cloud等详细讲解,也有详细的学习规划图,面试题整理等,我感觉在面试这块讲的非常清楚:

a3961401的博客 3863
上一篇: Java中的String到底占用多大的内存空间?带你一步步验证!
下一篇: 超强、超详细的Redis知识点汇总合集(工作、面试必备)
XingXing_Java
博客等级 码龄7年 278粉丝 89原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值