Loop и Bruno Conde в значительной степени покрыли это, но с тех пор, как я написал этот код ...
Целью разработки было избежать вызова пользователем механизма освобождения - мьютекс может собирать мусор, когда пользователь больше не ссылается на него.
Зачем нам нужно оборачивать WeakReference
вокруг экземпляров Mutex?
Карта Слабая Карта Хэша :
private final Map mutexMap = new WeakHashMap();
Эта карта используется для хранения ссылки на мьютекс, но если вы используете один и тот же объект для ключа и значения, этот объект не подходит для сборки мусора. Javadoc:
Примечание о реализации: объекты значения
в WeakHashMap проводятся обычные
сильные ссылки. Таким образом, забота должна быть
приняты, чтобы убедиться, что объекты значения делают
не сильно ссылаться на свои ключи,
прямо или косвенно, так как
это помешает ключам быть
отбрасываются. Обратите внимание, что объект значения
может косвенно ссылаться на свой ключ через
сама WeakHashMap; это
объект значения может сильно ссылаться на
какой-то другой ключевой объект, чей связанный
объект стоимости, в свою очередь, настоятельно относится
к ключу первого объекта значения.
Один из способов справиться с этим - обернуть
сами ценят в
Слабые ссылки перед вставкой, как
в: m.put (ключ, новый
WeakReference (значение)), а затем
разворачивание при каждом получении.
Не правда ли?
лучше просто создать карту из
Строка -> Мьютекс?
Когда это строковое значение будет собираться мусором? Одна и та же ссылка передается каждый раз? intern () вызывается на нем? Если я позвоню стажеру, как долго будет жить String? Если ключ является строкой, мьютекс может не подходить для сборки мусора в течение долгого времени после того, как нет необходимости сохранять ссылку на него.
Зачем нам звонить пут дважды?
Необходимо обработать два случая, пока метод не сможет получить надежную ссылку на мьютекс на карте:
- Слабая ссылка была собрана сборщиком мусора (или вообще никогда не была там)
- содержимое WeakReference является мусором, собранным после получения ссылки на него
put будет вызываться только один раз; метод возвращается сразу после.
(Слабая ссылка может быть повторно использована во втором случае, но я не вижу, чтобы это было существенным улучшением.)
Конечно, если кто-то может найти ошибку в коде, дайте мне знать, и я с радостью исправлю это. Кроме того, модульные тесты пытаются проверить, что реализация не протекает, поэтому не стесняйтесь изменять код и смотрите, что происходит при запуске тестов.