Совместное использование переменных внутри статического метода - PullRequest
10 голосов
/ 03 августа 2010

У меня есть вопрос о переменных внутри статического метода. Переменные внутри статического метода совместно используют одну и ту же область памяти или они будут иметь отдельную память?

Вот пример.

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 ]

15 голосов
/ 03 августа 2010

Они по-прежнему локальные переменные - они не разделяются между потоками.Тот факт, что они находятся внутри статического метода, не имеет значения.

Если вы используете переменную static в качестве промежуточной переменной, то будет небезопасным:

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.

4 голосов
/ 03 августа 2010

Потоки не будут перезаписывать значения друг друга, поскольку переменные полностью находятся в стеке.Каждый поток имеет отдельный стек.

1 голос
/ 03 августа 2010

Нет, они не разделяют одно и то же место в памяти.Для вашего звонка они вернут (в указанном вами порядке): 10, 20 и 30.

Честно говоря, с вашим кодом это будет верно в любом случае (так как выВы просто присваиваете значение, ничего не делая с ним), но подумайте:

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;
   }
}

Поскольку метод Static не может получить доступ к переменной экземпляра (по крайней мере, не безимея ссылку на экземпляр), нет способа инициализировать переменную один раз в статическом методе без повторной инициализации при каждом вызове кода.Чтобы позволить статическому методу изменять переменную, вам потребуется передать два значения для работы друг с другом.

1 голос
/ 03 августа 2010

Это не потокобезопасный метод, но все автоматические переменные являются поточно-безопасными автоматически, поскольку при каждом вызове функции вы получаете новый кадр стека. Все местные жители создаются при входе в функцию и уничтожаются при выходе. Как сказано выше, если бы вы использовали статическое хранилище, вы бы получили неожиданные результаты.

...