Переменная экземпляра Java, на которую ссылается локальная переменная. Память, безопасность потоков и финализация

У меня есть класс MyClass, у которого есть метод с переменной - экземпляр OtherClass, как показано ниже.

public class Myclass{ 
   public void meth1(){
 
  OtherClass other = new OtherClass();  
    other.perform();
     
    }

}

public class OtherClass{

private Map<String, String> ops = new HashMap<>();

public void perform(){

  // put/ remove values in ops 
    }

} 

Это многопоточная среда. Когда поток выполняет метод meth1(), где создается карта? в куче? Есть ли проблемы с безопасностью потоков по отношению к карте, объявленной как переменная экземпляра. Когда локальная переменная очищается от мусора, я предполагаю, что карта также очищается от мусора. Пожалуйста, поправьте, если я ошибаюсь.

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


person Tech User    schedule 07.05.2020    source источник
comment
Если речь идет о нескольких потоках, вызывающих только meth1, ничего не может произойти.   -  person akuzminykh    schedule 07.05.2020


Ответы (2)


Когда поток выполняет метод meth1(), где создается карта? в куче?

Да. Все, что вы создаете с помощью new Whatever(), хранится в куче, как экземпляр OtherClass, так и его HashMap (поскольку его инициализация включает выражение new HashMap<>()). И каждый раз, когда вы выполняете new Whatever(), вы получаете совершенно новый экземпляр в куче.

Есть ли проблемы с безопасностью потоков по отношению к карте, объявленной как переменная экземпляра.

Нет, не в вашем примере. Только если несколько потоков обращаются к одному и тому же экземпляру OtherClass, безопасность потоков может стать проблемой. В вашем случае каждый поток выполнения создает свой отдельный экземпляр OtherClass (в локальной переменной other), использует только его и не передает его в любое место, где его может увидеть другой поток.

Когда локальная переменная очищается от мусора, я предполагаю, что карта также очищается от мусора.

Да, если вы не добавите код, передающий Карту какой-либо другой части программного обеспечения.

Экземпляры собираются мусором, когда на них больше не ссылается какая-либо «живая» переменная/параметр/объект/... В вашем случае на ops HashMap ссылается (хранится) только поле ops его окружающего OtherClass экземпляра. Таким образом, когда этот экземпляр больше недоступен, карта также становится недоступной и, следовательно, готова к сборке мусора.

Одно замечание: сборка мусора не происходит в тот же момент, когда что-то становится недоступным, она запланирована каким-то сложным оптимизированным алгоритмом. Единственное, в чем вы можете быть уверены, так это в том, что это произойдет до того, как у вас закончится память.

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

Это верно только в противоположном направлении: вы не можете столкнуться с проблемами безопасности потоков/повреждения данных, если у вас нет полей экземпляра или класса.

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

person Ralf Kleberhoff    schedule 07.05.2020

Объект OtherClass будет создан в куче, а ссылка на него будет создана в стеке. Благодаря stack confinement этот код полностью потокобезопасен. Проблемы с безопасностью потоков возникают только тогда, когда состояние объекта совместно используется несколькими потоками. Поскольку доступ к этому объекту может получить только поток, вызывающий метод, он не является общим. Как только стек выскочит, объект будет удален сборщиком мусора.

person Prashant Pandey    schedule 07.05.2020
comment
может быть сборщиком мусора. Нет никакой гарантии, произойдет ли это и когда это произойдет, но в любом случае это не имеет значения. - person Holger; 07.05.2020
comment
Да, на самом деле я удалил это из своего ответа, если быть точным. Но гарантии нет, вы правы. - person Prashant Pandey; 07.05.2020