【问题标题】:Variable sharing inside static method静态方法内部的变量共享
【发布时间】:2011-03-24 22:00:10
【问题描述】:

我对静态方法中的变量有疑问。 静态方法中的变量是共享相同的内存位置还是有单独的内存?

这是一个例子。

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)=?

【问题讨论】:

标签: c# static-methods local-variables


【解决方案1】:

它们仍然是局部变量——它们不在线程之间共享。它们位于静态方法中这一事实没有任何区别。

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

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 设置的值。

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

        不,它们不共享内存中的相同空间。对于您的呼叫,他们会返回(按您列出的顺序):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;
           }
        }
        

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

        【讨论】:

        • 是的。很少使用它们,我忘记了它们……但是,对于这个特定的问题,这似乎不是问题。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-11-12
        • 2011-01-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-07-12
        • 2015-10-14
        相关资源
        最近更新 更多