Резьбонарезной безопасности:
Это потокобезопасный в некотором смысле. После вызова close
дальнейшие вызовы put
и remove
не повлияют на состояние карты, к которой относится concurrentHashMap
.
Однако вызовы put
и remove
до следующего open
приведут к потере обновлений. Это кажется мне плохим дизайном ... учитывая, что очевидным моментом open
и close
является предотвращение потери обновлений. Это может быть проблемой безопасности потока на другом уровне.
Эффективность:
С одной стороны: я замечаю, что все обновления карты выполняются, пока вы удерживаете замок. Учитывая это, я не думаю, что есть смысл использовать ConcurrentHashMap
. Использование обычного HashMap
было бы поточно-ориентированным и более эффективным.
С другой стороны, поскольку все обновления выполняются при удержании блокировки, блокировка является узким местом параллелизма, и потенциальные преимущества параллелизма при использовании ConcurrentHashMap
спорны.
Я думаю, я бы реализовал это, используя AtomicReference
( javadoc ) ... и без блокировки. Хитрость заключается в том, чтобы использовать ref.getAndSet(new ConcurrentHashMap())
, чтобы «переключить» существующую карту на новую пустую.
AtomicReference
по-прежнему будет узким местом параллелизма, но в гораздо меньшей степени, и вы можете избежать "закрытой ... открытой" дыры, выполнив два действия как одну атомарную операцию.
См. Ответ @ Holger для примера решения с использованием AtomicReference
..., отмечая, что его версия не решает проблему "закрыть ... открытое отверстие".