Скажем, у вас есть такой код:Создание объекта для кеша, «асинхронно» (вид), в Java: howto?
public final class SomeClass
{
private final Map<SomeKey, SomeValue> map = new HashMap<SomeKey, SomeValue>();
// ...
public SomeValue getFromCache(final SomeKey key)
{
SomeKey ret;
synchronized(map) {
ret = map.get(key);
if (ret == null) {
ret = buildValue(key);
map.put(key, ret);
}
}
return ret;
}
//etc
}
Проблема заключается в производительности: если buildValue()
является дорогостоящей функцией, то один абонент, имеющий построить его значение будет блокировать все остальные абоненты, стоимость которых может уже существовать. Я хотел бы найти механизм, в котором вызывающий должен построить значение, будет не заблокировать других абонентов.
Не могу поверить, что эта проблема не была решена (и решена) уже. Я попытался найти решение для решения проблемы, но не смог найти его. У вас есть ссылка, чтобы сделать это?
Я думал об использовании ReentrantReadWriteLock
, но ничего не мог придумать.
Это выглядит очень интересно! У меня уже есть Guava как зависимость, поэтому я обязательно попробую это. Спасибо за подсказку! – fge
Действительно. Репликация этого с помощью «ConcurrentHashMap» действительно сложна, просто потому, что 'putIfAbsent' заставляет вас заплатить стоимость вычисления значения уже, а альтернатива представляет собой причудливый цикл do-while, который все же может оказаться дублированным. –