2013-02-26 4 views
0

Я пытаюсь реализовать сервлет для мониторинга GPS и пытаюсь создать простой кеш, потому что я думаю, что он будет быстрее, чем SQL запрос на каждый запрос Http. простая схема:hashmap cache in servlet

в методе init(), я читаю одну точку для каждого автомобиля в HashMap (идентификатор автомобиля = ключ, местоположение в json = значение). после этого, какой-то запрос попытается прочитать эти пункты, и некоторый запрос попытается обновить (один автомобиль обновит один пункт). Конечно, я хочу, чтобы свести к минимуму синхронизации, так что я прочитал документацию: http://docs.oracle.com/javase/6/docs/api/java/util/HashMap.html

Обратите внимание, что эта реализация не синхронизирована. Если несколько потоков обращаются к карте хешей одновременно, и по крайней мере один из потоков изменяет структуру структурно, она должна быть синхронизирована извне. (Структурная модификация не является любая операция, которая добавляет или удаляет один или несколько отображений, просто изменяя значение, связанное с ключом, который экземпляр уже содержит не структурная модификация.)

Если я прав, то нет любая синхронизация в моей задаче, потому что я делаю только «не структурную модификацию == изменение значения, связанного с ключом, который уже содержит экземпляр»). это правильное утверждение?

ответ

0

Использование ConcurrentHashMap не использует синхронизацию блокировками, а атомарными операциями.

0

Неправильно. Добавление элемента в хэш-карту является структурной модификацией (и для реализации кеша вы должны добавить элементы в какой-то момент).

Используйте java.util.concurrent.ConcurrentHashMap.

+0

но если нет добавления (кроме как в init(), которые выполняются в однопоточном режиме), а только для изменения, все еще неправильно? –

0

Если я правильно понимаю, у вас есть два типа запроса:

  • Чтение из кэша
  • Запись в кэш (для обновления значения)

В этом случае, вы можете потенциально попытайтесь одновременно записать на одну и ту же карту одновременно, на что ссылаются документы.

Если все запросы проходят один и тот же фрагмент кода (например, метод обновления, который может быть вызван только из одного потока), вам не потребуется синхронизация.

Если ваша система имеет многопоточность и у вас есть несколько потоков или фрагментов кода, которые записываются на карту, вам нужно будет синхронизировать вашу внешнюю карту или использовать ConcurrentHashMap.


Для ясности, причина вам нужна синхронизация в том, что если у вас есть две темы, и пытается обновить значение JSON для того же самого ключа, который выигрывает? Это либо лишено шансов, либо приводит к исключениям или, что еще хуже, к ошибкам.

Каждый раз, когда вы изменяете один и тот же элемент из двух потоков, вам нужно синхронизировать этот код или, еще лучше, использовать поточно-безопасную версию структуры данных, если это применимо.

+0

один кусок кода (один метод), многопоточные, но разные потоки обновляют разные элементы. И что? –

+0

Вы не должны думать о «модификации» или «обновлении» элемента, подумайте, что вы пишете значение в этом месте на карте и заменяете предыдущий. Так что да, вам потребуется синхронизация. Только для чтения элементов не требуется синхронизация – HXCaine

0

, если все записи считываются в HashMap в init(), а затем только для чтения/Модифицированные - тогда да, все остальные потоки теоретически не нужно синхронизировать, хотя могут возникнуть некоторые проблемы из-за потоков кэширования значений, так ConcurrentHashMap было бы лучше.

возможно, а не реализации кэш самостоятельно, использовать кэширование simple implementation found in Guava library

+0

Не могли бы вы объяснить, в чем именно проблема? связанные с неатомной модификацией? –

0

не простая проблема - но это известно один. Прежде чем начать, я бы тщательно измерил, что у вас действительно есть проблемы с производительностью, и действительно ли кеширование действительно решает проблему. Вы можете подумать, что это должно быть, и вы можете быть правы. Вы также можете ошибаться в зависимости от ситуации («Упреждающая оптимизация - это корень всего зла»), поэтому измерьте.

Это говорит о том, что не выполняйте кеш самостоятельно, используйте библиотеку, которая сделает это за вас. У меня есть отличный опыт работы с ehcache.