Локальные переменные в статическом методе и безопасности потоков

20

У меня вопрос о области видимости переменной.

Например:

class A {
    private static void test() {
        // do something with local variables
    }
}

Теперь я создаю два потока и создаю один экземпляр A для каждого потока.

  1. Когда я вызываю test() в каждом потоке, могу ли я гарантировать, что test() является потокобезопасным?

  2. Где хранятся локальные переменные в test() ? Стек каждого потока? Кучное пространство?

P.S. Я знаю, что статичность совершенно бессмысленна в этом случае. Я нашел это в нашем устаревшем коде; Я просто хочу убедиться, что знаю!

    
задан Daehee Han 18.07.2012 в 08:11
источник

3 ответа

30

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

Локальные ссылки на объекты немного разные. Сама ссылка не разделяется. Однако указанный объект не сохраняется в локальном стеке каждого потока. Все объекты хранятся в общей куче. Если объект, созданный локально, никогда не ускользает от метода, в котором он был создан, он является потокобезопасным. Фактически вы также можете передать его другим методам и объектам, если ни один из этих методов или объектов не передаст переданный объект другим потокам.

Элементы объекта хранятся в куче вместе с объектом. Поэтому, если два потока вызывают метод в одном экземпляре объекта, и этот метод обновляет члены объекта, этот метод не является потокобезопасным.

Проверка безопасности потока. Если ресурс создан, используется и размещен внутри элемента управления одним и тем же потоком, и никогда не избегает управления этим потоком, использование этого ресурса является безопасным потоком.

От: Ссылка

    
ответ дан Erol 18.07.2012 в 08:18
  • +1, хотя вы можете «передать», (сигнал), объекты на другие потоки, но поток, который его создал, должен обычно «отказаться от владения», например. путем обнуления его собственной ссылки или перезаписи, создавая другой объект, так что два потока никогда не смогут работать на одном и том же объекте. Если это не сделано, объект будет общим, как вы описали, и потребует блокировок для доступа. –  Martin James 18.07.2012 в 08:31
  • Да, по этой причине удаление объекта путем обнуления ссылки является хорошей идеей. –  Erol 18.07.2012 в 08:33
  • Великий Я собирался задать этот вопрос !!!! –  JohnMerlino 30.06.2014 в 23:27
3

Когда я вызываю test () в каждом потоке, могу ли я гарантировать, что test () является потокобезопасным?

  

Да, это было бы поточно-безопасным, если в методе test (), над которым вы работаете   локальные переменные метода.

Где хранятся локальные переменные в test ()? стек каждой нити? пустое пространство?

  

Метод Локальная переменная хранит собственный стек каждого потока.

    
ответ дан Pramod Kumar 18.07.2012 в 08:18
0

Для номера 1 я не знаю, что test() делает, поэтому я не могу ответить. Если они изменяют некоторую переменную static класса A, то она может быть небезопасной по потоку. Если оба потока по пути даны ссылкой на один и тот же объект, в зависимости от того, как определяется объект, он может быть небезопасным потоком.

Для номера 2 локальные переменные находятся в стеке каждого потока (или, по крайней мере, концептуально подобным образом), поэтому нет никаких проблем в отношении изменения локальных переменных другими потоками.

    
ответ дан nhahtdh 18.07.2012 в 08:16