PUSH [position in this method we're at right now]
GOTO [position of the start of the b method]
b()方法以一条指令结束,这意味着:从堆栈中弹出一个数字,然后转到该数字
局部变量也存储在堆栈上。所有这些的指令集基本上是:
1 PUSH 4 // position to return back to once a is done
2 PUSH 5 // from a(5)
3 GOTO 8 // a method
4 PUSH 7
5 CREATE_OBJECT "Done" // pushes pos of new object on stack
6 GOTO [position of System.out.println]
7 EXIT_APPLICATION
8 PUSH 10 // position to return back to
9 GOTO 16 // b() method
10 CREATE_OBJECT "In a: " // pushes pos of new object on stack
11 FLIP // flip the top two stack entries
12 CONCAT_STRINGS
13 PUSH 15 // position to return back to
14 GOTO [position of System.out.println]
15 RET // pop number and go to it
16 RET
List<String> list = new ArrayList<String>();
list.add("Hello");
add1(list);
System.out.println(list);
public void add1(List<String> list) {
list.add("World!");
}
每当任何线程(主线程除外)开始执行“factorial(int number)”方法时,该线程都会将“number”的一个副本作为局部变量保存到自己的堆栈中,因此任何其他线程都不可能更改“number”的值
然而,如果“number”值来自任何共享对象(由多个线程共享),并且如果它被多个线程复制到stack&;在某些线程更改了该值之后,在这种情况下可能会出现数据不一致的情况(请检查“volatile”)
多个线程确实可以安全地调用
MathUtils.factorial()
每次激活
factorial
都会有自己的f
副本,可以单独访问。这就是“局部变量”的含义参数
number
不被修改,在任何情况下都像一个局部变量'factorial'至于你在评论中的问题。不,代码只有一份,不需要再多拿一份。但是每个线程都有自己的代码执行,所以如果将其视为一个“单独的副本”会有所帮助,那么在概念上不会造成太大的伤害
您需要了解的具体机制是堆栈
每个线程都有自己的堆栈。堆栈是一种传统的后进先出设置:可以“推”堆栈上的内容,也可以“弹出”堆栈上的内容,这将检索并删除最近推的内容
每个线程都有自己独特的堆栈。堆栈用于局部变量和执行指针。想象一下这个代码:
现在想象你是一个CPU。你只是被指向一条指令,应该运行它。你不懂java,也不知道循环是什么。你只知道基本的指令,包括“去”。但你只有这些
b()运行完毕后,您如何知道返回到哪里?您怎么知道必须跳回方法的中点并继续
System.out.println("In a")
堆栈就是答案。当执行
b()
时,引擎盖下发生的是:b()方法以一条指令结束,这意味着:从堆栈中弹出一个数字,然后转到该数字
局部变量也存储在堆栈上。所有这些的指令集基本上是:
(这是非常简单的;CPU和字节码比这复杂得多,但希望它能让人明白这一点!)
堆栈作为一个概念解释了java的工作原理:
b
是一个局部变量或参数,就像是一条指令,读取一本书中的一行“在你当前阅读的地方的上面两行”(只要你继续阅读,这将是一个新行),而不是一条指令,读取“本书中的第8行”,每次都是同一行李>上面打印的是5而不是6,因为
add1(x)
是以下内容的缩写:add1将对这个推送值进行操作,而不是对x变量进行操作。当我们涉及到物体时,它会变得有点复杂(因为java中的对象是由它们的引用来表示的:指针。想象一个对象是一所房子,而引用更像是一个地址。我可以有一个我房子的地址,然后在一张纸上递给你一份该地址的副本。你可以拿一支笔随意更改那张纸,这不会影响我的地址簿或地址。)我的房子。但是如果你开车到房子里,把一块砖头扔进窗户,即使我递给你一份我的通讯录,那仍然是我的窗户。所以:
这个将打印^{。因为
.
在java中相当于“开车去地址list
所指的房子”。如果我写了list = List.of("Hello", "World!")
,似乎什么也不会发生,因为=
相当于java:擦除地址卡并在其上写一个新地址。这不会影响我的房子和通讯录相关问题 更多 >
编程相关推荐