7

мне нужна карта со следующими требованиями:Параллельной Карте с фиксированным размером

  1. Это должно быть весьма одновременно. Методы put(), get() и remove() могут вызываться одновременно несколькими потоками.

  2. Он должен быть фиксированного размера. Если размер HashMap достигает максимального значения (например, 10000), добавление новой записи на карту не допускается. Он НЕ МОЖЕТ быть кешем LRU, где самая старая запись удаляется при достижении максимального размера.

ConcurrentHashMap может удовлетворить # 1. Но не уверен, как №2 можно реализовать поверх ConcurrentHashMap без влияния на параллелизм (добавление настраиваемого метода put(), который будет добавляться к карте только тогда, когда размер меньше максимального размера, должен быть «синхронизирован». цель использования параллельного HashMap).

Пожалуйста, дайте мне знать ваши мысли.

+3

проверить размер перед тем, как положить? – vefthym

+2

в concurrenthashmap размер сообщения не является точным. возможно, использовать concurrenthashmap с счетным семафором? –

+1

«не уверен, как №2 можно реализовать поверх ConcurrentHashMap без влияния на параллелизм» ... Я не понимаю, почему это будет проблемой. Вы создаете обертку, которая на вершине параллельной карты вводит счетчик. Для синхронизации доступа к счетчику вы используете свой собственный примитив syncronizing (например, ReentrantLock), чтобы свести к минимуму дополнительные служебные данные и отделить его от параллельной синхронизации карт. Тогда все должно работать нормально – heorhi

ответ

6

Вы может реализовать карту, которая делегирует ConcurrentHashMap, используя счетный семафор, чтобы ограничить количество элементов на карте. Класс Semaphore использует атомарно обновляемый int для отслеживания разрешений, поэтому он не будет нести дополнительные дополнительные накладные расходы.

+2

Используйте 'TryAcquire'' Семафор' перед 'put' и' release' после 'remove', так как вы не хотите блокировать. –

2

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

Например, в Ehcache вы можете добиться того, что вы хотите с помощью конфигурации, аналогичной конфигурации:

<cache 
name="myCache" 
maxElementsInMemory="10000" 
eternal="true" 
overflowToDisk="false" /> 
+0

Главное, что это будет на несколько порядков медленнее. –

+0

Я могу согласиться с тем, что в этом случае снова следует выбирать, когда нужно выбирать, что нужно оптимизировать. Некоторые из распределенных хеш-карт, которые я использую, хранят миллионы данных в отдельных регионах с соответствующими службами, отвечающими в течение приемлемых временных рамок. Учитывая все это, 10000 - очень небольшое число. – Pumpkin

+1

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

0

При использовании ConcurrentHashMap, который здесь является очевидным выбором, используйте вход concurrencyLevel для конструктора, чтобы увеличить пропускную способность - это сегментирует карту в несколько зон, чтобы избежать конфликтов puts.

+0

Изменение 'concurrencyLevel' никак не затрагивает его проблему ConcurrentMap фиксированного размера. –

+0

Согласовано. Это не касается проблемы с фиксированным размером ConcurrentMap. –

+0

Согласился и со мной, но это улучшит параллелизм, что было его другой заботой. Стоит отметить. –

0

Как сохранить размер Hashmap в любое время, чтобы обеспечить общее количество вставленных элементов? Вы можете использовать AtomicInteger, так что вам не нужно синхронизировать/блокировать обычный int и жертвовать преимуществами использования ConcurrentHashMap.

Смежные вопросы