В дополнение к ответу Кена, если создать тяжелый объект, который позже будет выброшен, НЕ приемлемо (вы хотите гарантировать, что по какой-либо причине создается только один объект для каждой клавиши), тогда вы можете сделать это. .. фактически, не делаем. Не делай этого сам. Используйте google-collections (теперь guava) MapMaker class:
Map<KeyType, HeavyData> cache = new MapMaker<KeyType, HeavyData>()
.makeComputingMap(new Function<KeyType, HeavyData>() {
public HeavyData apply(KeyType key) {
return new HeavyData(key); // Guaranteed to be called ONCE for each key
}
});
Тогда просто cache.get(key)
просто работает и полностью удаляет вас от необходимости беспокоиться о сложных аспектах параллельности и syncrhonization.
Обратите внимание, что если вы хотите, чтобы добавить некоторые причудливые особенности, как и истечение срока действия, это просто
Map<....> cache = new MapMaker<....>()
.expiration(30, TimeUnit.MINUTES)
.makeComputingMap(.....)
и вы также можете легко использовать мягкие или слабые значения либо ключи или данные в случае необходимости (см Javadoc более подробности)
Просто интересно: каковы ваши требования к кешированию? Вам нужно кэшировать полное транзитивное закрытие вашего объекта с тяжелым весом, чтобы он был согласован в кластере серверов приложений? Если это так, это нетривиальная проблема для решения, и вам может быть лучше использовать библиотеку кеша, такую как ehcache. – Alan