Мне интересно, каким будет лучший подход к этой проблеме.У меня есть (абстрактно говоря) простой метод, который вызывает веб-сервис и сохраняет результат в локальном кеше в памяти, что-то вроде:
public Document callWebservice(SomeObject parameter) {
Document result = cache.get(parameter);
if (result == null) {
result = parse(retrieve(parameter));
cache.put(result);
}
return result;
}
Теперь, если документ находится в кеше, он может простовернуть без проблем, хорошо.В однопоточной среде этот подход тоже работает отлично.Однако в многопоточной среде выясняется, что каждый поток будет обращаться к биту 'else' и вызывать веб-сервис несколько раз.
Я мог бы перебросить синхронизированный блок в части 'else', но яПоверьте, это слишком «широкий» размер блокировки - весь метод будет недоступен для вызова потоков, даже если они вызывают совершенно разные вещи.
Хорошо, если веб-служба вызывается дважды, если запрос другой (т. е. параметр SomeObject, в данном случае).
Теперь вопрос: какой подход лучше использовать в этом случае?
Я думал о сохранении параметра в коллекции (threadsafe)объект.Если содержимое параметра одинаково, он выдаст тот же результат hashCode / equals и будет найден в объекте коллекции, указывая, что другой поток уже обрабатывает этот запрос.Если это так, вызывающий поток может быть приостановлен, пока не вернется веб-служба.(Я должен был бы выяснить, как заставить вызывающий поток ждать все же).Будет ли это работать с блокировкой объекта параметра SomeObject
?например:
private Map<SomeObject, SomeObject> currentlyProcessingItems = new ConcurrentHashMap<SomeObject, SomeObject>();
public Document callWebservice(SomeObject parameter) {
if (currentlyProcessedItems.contains(parameter)) {
parameter = currentlyProcessedItems.get(parameter);
} else {
currentlyProcessedItems.putIfAbsent(parameter);
}
synchronized(parameter) {
Document result = cache.get(parameter);
if (result == null) {
Document result = parse(retrieve(parameter));
cache.put(result);
}
currentlyProcessedItems.remove(parameter);
return result;
}
}
(примечание: логика для отслеживания текущих обрабатываемых запросов, использования ConcurrentHashMap и блокировки может быть неоптимальной или совершенно неправильной)
Нет, я фактически никогда не заканчивал читатькнига по резьбе.Я должен.
Я уверен, что эта конкретная проблема встречается довольно часто, я просто не смог найти ответ.Как называется такая ситуация (т. Е. Блокировка определенного объекта), если можно спросить?