Совместное использование переменных внутри статического метода
У меня вопрос о переменных внутри статического метода.
Имеют ли переменные внутри статического метода одинаковое расположение памяти или имеют ли они отдельную память?
Вот пример.
public class XYZ
{
Public Static int A(int value)
{
int b = value;
return b;
}
}
Если три разных пользовательских вызова выполняют метод A
XYZ.A(10);
XYZ.A(20);
XYZ.A(30);
одновременно. Какими будут возвращаемые значения для каждого вызова?
XYZ.A(10)=?
XYZ.A(20)=?
XYZ.A(30)=?
Ответы
Ответ 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
Нет, они не используют одно и то же пространство в памяти. Для вашего вызова они вернутся (в указанном порядке): 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 не может получить доступ к переменной экземпляра (по крайней мере, не имея ссылки на экземпляр), нет возможности инициализировать переменную один раз в статическом методе без повторной инициализации при каждом вызове кода. Чтобы позволить статическому методу изменять переменную, вам нужно передать два значения для работы на eachother.