11

我对静态方法中的变量有疑问。静态方法中的变量是否共享相同的内存位置,或者它们是否有单独的内存?

这是一个例子。

public class XYZ
{
    Public Static int A(int value)
    {
      int b = value;
      return b;
    }
}

如果 3 个不同的用户调用执行方法 A

XYZ.A(10);
XYZ.A(20);
XYZ.A(30);

同时。每次调用的返回值是多少?

XYZ.A(10)=?
XYZ.A(20)=?
XYZ.A(30)=?
4

4 回答 4

17

它们仍然是局部变量——它们不在线程之间共享。它们在静态方法中的事实没有什么区别。

如果您使用静态变量作为中间变量,那是不安全的:

public class XYZ
{
    // Don't do this! Horribly unsafe!
    private static int b;
    public static int A(int value)
    {
        b = value;
        return b;
    }
}

在这里,所有线程将真正使用相同的b变量,因此如果您同时从多个线程调用该方法,线程 X 可以写入b,然后是线程 Y,因此线程 X 最终返回由线程 Y 设置的值。

于 2010-08-03T19:10:46.110 回答
4

线程不会覆盖彼此的值,因为变量完全在堆栈上。每个线程都有一个单独的堆栈。

于 2010-08-03T19:10:38.547 回答
1

这不是线程安全的方法,但所有自动变量都是自动线程安全的,因为每次调用该函数时,您都会获得一个新的堆栈帧。所有的局部变量都是在进入函数时创建并在退出时销毁。如上所述,如果您使用了静态存储,那么您会得到意想不到的结果。

于 2010-08-03T19:15:07.893 回答
1

不,它们在内存中不共享相同的空间。对于您的呼叫,他们会返回,(按您列出的顺序):102030

老实说,对于您的代码,这在任何情况下都是正确的(因为您只是在分配一个值,而不是对它做任何事情),但请考虑:

Class XYZ
{
   public static int A (int value)
   {
      b += value;  \\Won't compile: b not initialized
      return b;
   }
}

或者

Class XYZ
{
   public static int A (int value)
   {
      int b = 0;  \\Initialized 'b' for each call
      b += value;  
      return b;
   }
}

由于静态方法不能访问实例变量(至少,不能没有对实例的引用),所以没有办法在静态方法中初始化变量一次,而不会在每次调用代码时重新初始化它。要允许静态方法更改变量,您需要传入两个值以相互操作。

于 2010-08-03T19:15:28.613 回答