我相信许多朋友都知道局部变量是线程安全的。
您知道局部变量为什么是线程安全的吗?前言当多个线程同时访问共享变量时,将导致并发问题。
因此,如果将变量放在方法内部,是否还会存在并发问题?如果没有并发问题,那么为什么没有并发问题呢?我记得上学时著名的斐波那契数列,我们都遇到了这样的问题,打印了斐波那契数列。
斐波那契数列是这样的序列:1、1、2、3、5、8、13、21、34 ...,这意味着第一项和第二项是1,从第三项开始,每一项等于前两项的总和。
我们可以使用以下代码生成斐波那契数列。
//生成斐波那契序列public int [] fibonacci(int n){//要存储结果的数组int [] result = new int [n]; //该数组的第一和第二项是1 result [0] = result [1] = 1; //为(int i = 2; i result [i] = result [i-2] + result [i-1]; return result;}计算项目3到n;假设许多线程在线程上调用fibonacci()方法,同时生成Fibonacci序列。
对于方法中的局部变量结果,是否存在线程安全问题?答案是:否!!!接下来,让我们分析为什么局部变量没有线程安全问题!我们以下面的三行代码为例:int x = 5; int [] y = fibonacci(x); int [] z = y;当我们调用fibonacci(x)时,CPU首先发现fibonacci()方法的地址,然后跳转到该地址以执行代码。
执行后,它需要返回并找到下一个调用该方法的语句int [] z = y的地址,然后跳转到该地址可以执行,我们可以简化该过程,如下图所示,这里需要注意的是,CPU将通过堆栈寄存器和retu查找调用方法的参数。
地址。
例如,有三种方法A,B和C。
调用关系是A调用B,B调用C。
在运行时,将构造相应的调用堆栈。
我们可以简单地使用下图来表示此调用堆栈。
每个方法在调用堆栈中都有自己的独立堆栈框架,每个堆栈框架都具有相应方法所需的参数和返回地址。
调用该方法时,将创建一个新的堆栈框架并将其压入调用堆栈;当方法返回时,将自动弹出相应的堆栈框架。
我们可以这样说:当调用该方法时创建堆栈帧,然后在调用时“销毁”堆栈帧。
方法返回时。
局部变量存储在哪里?局部变量的范围在方法内部。
执行该方法时,局部变量是无用的。
可以说,当方法返回时,局部变量将“死”。
这时,我们将考虑调用堆栈的堆栈框架。
没错,局部变量存储在调用堆栈中。
这时,我们可以使用下图来表示该方法的调用堆栈。
许多人都知道局部变量存储在堆栈中。
如果变量需要跨越方法的边界,则必须在堆中创建它。
调用堆栈和线程两个线程可以同时使用不同的参数调用同一方法。
所以问题是,调用堆栈和线程之间的关系是什么?答案是:每个线程都有自己的独立调用堆栈。
我们可以使用下图简单地表示这种关系。
在这一点上,让我们在以下内容的开头看一个问题:Java方法内部的局部变量是否存在并发问题?答案是没有并发问题!因为每个线程都有自己的调用堆栈,所以局部变量存储在线程的相应调用堆栈中,并且不会共享,因此自然不会出现并发问题。
线程关闭方法中的局部变量将不会与其他线程共享,因此不会出现并发问题。
这种解决问题的技术也称为线程关闭。
官方解释是:仅在单个线程中访问数据。
由于没有共享,因此即使未设置同步,也不会存在并发问题!我特别推荐一种高质量的内容共享架构+算法。
如果您没有关注,则可以长按以关注它:长按以订阅更多令人兴奋的内容▼如果您已了解,请单击以查看,由衷的感谢。
免责声明:本文内容由21ic经授权发布,版权归原作者所有,该平台仅提供信息存储服务。
本文仅代表作者的个人观点,并不代表该平台的立场。
如有任何疑问,请与我们联系,谢谢!