Как эффективно использовать String в качестве ключа WeakHashMap в Java или альтернативное решение

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

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

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

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

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


person CorrieKay    schedule 13.04.2014    source источник
comment
Можете ли вы конкретно описать, какая у вас проблема с использованием строковых значений в качестве ключей?   -  person Warren Dew    schedule 13.04.2014
comment
Ну, честно говоря, результаты никогда не предсказуемы. Здесь у меня есть две карты: стандартная хэш-карта, в которой хранятся объекты данных, предназначенные для онлайн-пользователей, и слабая карта для кэшированных пользователей. Иногда он отказывается удалить его даже при отсутствии ссылок (сильная ссылка на хэш-карту удаляется при выходе пользователя из системы), а иногда удаляет ее, пока в основной хэш-карте есть сильная ссылка, пока пользователь находится в сети. Результаты крайне непредсказуемы :\   -  person CorrieKay    schedule 13.04.2014


Ответы (1)


Причина его непредсказуемого поведения объясняется в Javadoc для WeakHashMap в последнем предложении этого абзаца:

Этот класс предназначен в первую очередь для использования с ключевыми объектами, чьи методы equals проверяют подлинность объекта с помощью оператора ==. После того, как такой ключ отброшен, его уже нельзя воссоздать, поэтому невозможно выполнить поиск этого ключа в WeakHashMap позднее и удивиться тому, что его запись была удалена. Этот класс отлично работает с ключевыми объектами, чьи методы equals не основаны на идентификаторе объекта, например экземпляры String. Однако с такими воссоздаваемыми ключевыми объектами автоматическое удаление записей WeakHashMap, чьи ключи были отброшены, может привести к путанице.

Что вам действительно нужно, так это карта, на которой записи удаляются при сборке мусора для значений, а не при сборке мусора для ключей, то есть, для которых значения являются слабыми, а не для которых слабые ключи. Вы можете найти помощь по этому вопросу в этом вопросе:

Карта слабых хэшей Java — необходимо удалить запись на основе слабости значения, а не ключа

person Warren Dew    schedule 13.04.2014
comment
Спасибо, хорошо, сэр:] Решение с гуавой сработало как абсолютный шарм! Самое приятное то, что всеобъемлющий API, над которым я работал, уже предоставил гуаву как часть набора инструментов! - person CorrieKay; 13.04.2014
comment
Я бы полностью согласился с частью этого документа, только если бы карты Java позволяли вам заменить объект, используемый для ключа. Поскольку вы можете только обновить его значение, во многих случаях он не работает, даже если вы учитываете отброшенные записи. Например, кэш объектов с дедупликацией WeakHashMap<T,WeakReference<T>> не может быть легко реализован, потому что ключ может стать несоответствующим объекту, хранящемуся в значении, когда значение нуждается в обновлении, потому что WeakReference был отброшен, а запись в карте еще не . - person Christopher; 12.08.2017