Можно ли получить слабодоступный объект через WeakReference

Я знаю, что такое WeakReference, и я прочитал его документацию, множество блогов и тем SO. Однако мне до сих пор неясно, может ли на самом деле произойти следующий поток.

  1. объект X, на который имеется сильная ссылка strRef и слабая ссылка weakRef
  2. strRef очищается в случайном потоке
  3. weakRef разыменовывается в случайном потоке
  4. ссылка, полученная на предыдущем шаге, назначается strRef

Есть много дискуссий о том, как слабые ссылки очищаются при сборке мусора, но, насколько мне известно, сборка мусора не происходит после каждой очистки ссылок. Следовательно, похоже, что слабодоступный объект потенциально может быть «воскрешен» на шаге №3 выше, если сборка мусора не произошла между этапами №2- №3.

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

Итак, существует ли спецификация, которая гарантирует, что объекты со слабыми ссылками не могут быть воскрешены, и есть ли какие-либо предостережения, связанные с многопоточностью?


person Vasiliy    schedule 20.12.2017    source источник
comment
да. Указание WeakReference или SoftReference предотвратит сборщик мусора указанного Object до тех пор, пока снова не останется сильных ссылок. Фактически, это та самая причина, по которой PhamtomReference не заслуживает уважения. Это не состояние гонки и не опасно. Это только неудобно, если вы не понимаете, как это работает - это то, как это должно работать.   -  person Boris the Spider    schedule 20.12.2017
comment
@BoristheSpider, я рассматриваю это как состояние гонки и опасно только в контексте моей текущей работы с pub-sub со слабыми подписчиками, а не в целом. Это может привести к тому, что подписчики (по всей видимости) случайным образом получат ложные уведомления даже после удаления всех сильных ссылок на них. В любом случае, спасибо за ваш вклад. У вас есть ссылки на соответствующие части документации или статей в блогах?   -  person Vasiliy    schedule 20.12.2017
comment
Я не понимаю, почему вы полагаетесь на достижимость, чтобы определить живучесть? Вы можете видеть, что в любом фреймворке, построенном вокруг pub / sub, акторы должны быть отключены явно, когда они будут выполнены - это предотвращает всякого рода странное поведение.   -  person Boris the Spider    schedule 20.12.2017
comment
Я создаю сложную и глубокую иерархию классов, связанных с пользовательским интерфейсом (в Android). Я подумал, что могу положиться на слабые ссылки, чтобы подписать эти классы пользовательского интерфейса на шину событий, чтобы потом не было необходимости отказываться от них. Наверное, все-таки не лучшая идея.   -  person Vasiliy    schedule 20.12.2017
comment
Точно, и на каждом уровне иерархии родитель сообщает своим потомкам, видны ли они в данный момент. Он также сообщит своим потомкам, будет ли он удален или добавлен к самому родителю. Этот простой DAG позволяет в значительной степени исправить все эти проблемы - он также позволяет обнаруживать циклы и другие подобные особенности.   -  person Boris the Spider    schedule 20.12.2017
comment
Слабая подписка - плохая идея. То, что приемники не удаляются, - это только одна возможная проблема. Обычно вы регистрируете не ссылку на компонент, а слушателя или аналогичный объект привязки. И если на этот объект есть только слабые ссылки, он может получить сборщик мусора, даже если целевой компонент все еще доступен. Таким образом, вам понадобится дополнительная ссылка от цели на слушателя, чтобы он оставался активным, что усложняет код, а не упрощает его.   -  person Holger    schedule 21.12.2017


Ответы (1)


Следовательно, похоже, что слабодоступный объект потенциально может быть «воскрешен» на шаге №3 выше, если сборка мусора не произошла между этапами №2- №3.

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

Такое состояние гонки очень неудобно и даже опасно, поэтому я думаю, что должно быть что-то, что этому препятствует,

Это то, что вы должны проверить в любой момент, если вы не знаете, когда фоновый поток очищает сильную ссылку. ПРИМЕЧАНИЕ: очистка сильной ссылки просто означает установку значения памяти на null и больше ничего.

есть ли спецификация, которая гарантирует, что объекты со слабыми ссылками не могут быть воскрешены, и есть ли какие-либо предостережения, связанные с многопоточностью?

Даже отброшенный объект можно воскресить, установив ссылку на this в методе finalise. Я бы рекомендовал вам не полагаться на такое поведение. Настройка ссылок не является источником обмена сообщениями или операцией, которая имеет много гарантий безопасности потоков.

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

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

person Peter Lawrey    schedule 20.12.2017