Как узнать значение, которое было связано с удаленной записью в WeakHashMap - PullRequest
4 голосов
/ 29 июня 2010

У меня что-то вроде этого:

 private Map<MyObj1, MyObj2> map = new WeakHashMap<MyObj1, MyObj2>();

 ... somewhere in the code ...
 MyObj1 myObj1 = new MyObj1();
 map.put(myObj1, new MyObj2();
 ...
 myObj1 = null;

... somewhere else in a thread ... (I would like to pass to a checkThis(MyObj2) method the Value associated with the entry that was removed from the Map)
/* something like this maybe */
while (true) {
    MyObj2 myObj2 = referenceQueue.remove().get();
    checkThis(myObj2);
}

MyObj1 ключ может быть удален, когда GC вступает в игру, и нет сильной ссылки на него.

Я бы хотел передать checkThis(MyObj2) конкретный объект-значение карты, связанный с удаленным ключом (возможно, проверяя ReferenceQueue?)

Я не могу понять, как поместить это в код.

Ответы [ 4 ]

1 голос
/ 06 июля 2010

Из комментария к другому ответу:

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

Это звучит как задание для HttpSessionBindingListener

0 голосов
/ 29 июня 2010

Из преамбулы WeakHashMap (курсив добавлен):

Реализация Map на основе хеш-таблицы со слабыми ключами.Запись в WeakHashMap будет автоматически удалена, если ее ключ больше не используется.Точнее, наличие сопоставления для данного ключа не будет препятствовать тому, чтобы ключ был отброшен сборщиком мусора , то есть сделан финализируемым, завершенным и затем восстановленным.Когда ключ отброшен, его запись эффективно удаляется с карты, поэтому этот класс ведет себя несколько иначе, чем другие реализации Map.

Однако WeakHashMap никогда не сообщает вам об этом "теряет "запись :-) Если вы заботитесь только о ключах в конкретном экземпляре во времени, то вы можете использовать сканирование карты (также практично только для некоторых n).В противном случае, следуйте своей догадке о ReferenceQueue.

Эта ссылка может быть полезна: Java Reference Objects

0 голосов
/ 29 июня 2010

Справочные очереди

Как только WeakReference начинает возвращать ноль, объект, на который он указал, стал мусором, а объект WeakReference практически бесполезен. Как правило, это означает, что требуется некоторая очистка; WeakHashMap, например, должен удалить такие несуществующие записи, чтобы избежать удержания постоянно растущего числа мертвых WeakReferences.

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

См. Эту страницу для обучения по использованию.

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

Edit:

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

HashMap aHashMap = new HashMap();
ReferenceQueue Queue = new ReferenceQueue();
MyWeakReference RefKey = new MyWeakReference(key, Queue);
aHashMap.put(RefKey, value);
0 голосов
/ 29 июня 2010

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

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

«Ключ MyObj1 удаляется, если на него нет явной ссылки»

не является точным.MyObj1 может быть выпущен GC, если у него нет сильных ссылок, но если нет необходимости выпускать его, он просто не будет выпущен.

...