У вас есть пара целей. Что делать, зависит от того, что вы пытаетесь сделать.
Так что в этом случае вы пытаетесь избежать повторных вычислений, но эти вычисления не особенно дороги. Вы можете столкнуться с проблемой конкуренции за блокировку. Поэтому, чтобы сделать его потокобезопасным, используйте ThreadLocal<Map<String, Fact>>
. Потенциально InheritableThreadLocal<Map<String, Fact>>
, где childValue
копирует Map
.
. Часто существует известный набор значений, которые могут быть общими, и вы просто хотите их получить. В этом случае вычислите Map
(или массив) во время статической инициализации класса.
Если вы хотите, чтобы маховики были распределены между потоками и были уникальными, используйте ConcurrentHashMap
with вместе с методом Map.computeIfAbsent
.
Если вы хотите, чтобы маховики распределялись между потоками, были уникальными, и вы хотели бы убедиться, что вы выполняете вычисления только один раз, это становится немного сложнее. Вы должны поместить (если отсутствует) заполнитель в ConcurrentMap
;если текущий поток выигрывает, замените его на вычисленное значение и сообщите, в противном случае дождитесь вычисления.
Теперь, если вы хотите, чтобы маховики собирались мусором, вы бы хотели WeakHashMap
. Это не может быть ConcurrentMap
с использованием коллекций Java SE, что делает его немного безнадежным. Вы можете использовать старый добрый замок. В качестве альтернативы значение может быть WeakReference<Fact>
, но вам нужно самостоятельно управлять выселением.
Возможно, сильная ссылка на Fact
сохраняется только периодически, но вы не хотите, чтобы она былавоссоздается слишком часто, и в этом случае вам понадобится SoftReference
вместо WeakReference
. Действительно, WeakHashMap
может вести себя , что на удивление , в некоторых случаях приводя к падению производительности до непригодного после ранее работающей безупречной работы.
(Обратите внимание, в этом случае ваш Map
было бы лучше набрать Integer
.)