2017-10-07 55 views
0

你能帮我吗?在函数中创建一个变量 - 多线程环境

我在Java中有一个函数'f'。该功能在多线程环境中工作

f() { 

SomeObject someO = new SomeObject(); 


    function1(someO); 
    . 
    . 
    . 
    function7(someO); 

} 

的问题:第一个线程进入函数“f”和创建SomeObject的新实例,然后调用功能1,函数2等。当第一个线程在function4中时,稍后的第二个线程进入该方法并创建SomeObject的新的初始化。问题是SomeObject的哪个实例将由函数5,6,7的其余部分中的第一个线程处理?

+0

来自两个不同线程的调用将创建两个不同的实例,将它们分配给两个不同的局部变量,并将每个实例传递给每个函数。你认为会发生什么,不同于此,为什么? – pvg

回答

1

第一个线程将SomeObject(aka some0)的实例作为局部变量,因此它是本地的,并因此位于该线程。它只能引用some0的那个实例。

任何其他调用f()的线程都将创建一个不同的实例,也称为some0,并且只能引用它的副本。

这些是局部变量的规则。如果some0是一个实例变量 - 即在f()之外声明 - 那么如果它们在f()的任何类的同一个实例上调用f(),则该变量可以由不同线程引用。

这些是规则 - 这是一个更完整的解释。

局部变量在堆栈中声明;这意味着,对于在方法中声明的任何变量,在用于该方法的调用的“栈帧”中存在用于其引用的空间。每次调用某个方法时,都会为该方法中的所有局部变量分配堆栈空间,因此它们的引用与该方法的任何其他调用都是分开的。所以如果一个不同的线程调用这个方法,它会为本地变量获取一个不同的栈帧。

同样的事情发生在递归过程中,即如果f()要自己调用。对于f()的每次调用,局部变量引用仍然是分开的,即,每次递归调用都有它们自己的副本。否则,使用递归将非常困难。

+0

注意到此行为由Java语言规范保证也很重要。通常这是一个好处:因为局部变量是每次调用一个方法时重新创建的,所以它们是*线程安全的*,因为它们与其他调用不共享内存。这通常用于并发编程,以保证局部变量在其他线程可以看到它们之前是安全的。 – markspace

0

第一个线程将处理SomeObject的第一个实例。每个线程创建自己的堆栈。以及它调用的任何方法以及它创建的任何本地对象都将位于该堆栈中,并且这些对象不受其他线程的影响。所以在你的情况下,线程1处理不会受线程2处理影响。

相关问题