7

muszę mapę z następujących wymogów:Jednoczesne Mapa ze stałym rozmiarze

  1. Należy wysoce współbieżne. Metody mogą być wywoływane przez wiele wątków jednocześnie.

  2. Powinien mieć stały rozmiar. Jeśli rozmiar HashMap osiąga maksymalną wartość (na przykład 10000), dodanie nowego wpisu do mapy nie powinno być dozwolone. NIE MOŻE to być pamięć podręczna LRU, w której najstarszy wpis zostanie usunięty po osiągnięciu maksymalnego rozmiaru.

ConcurrentHashMap może spełniać # 1. Nie wiem jednak, w jaki sposób # 2 można wdrożyć na podstawie ConcurrentHashMap bez wpływu na współbieżność (dodanie niestandardowej metody put(), która zostanie dodana do mapy tylko wtedy, gdy rozmiar jest mniejszy niż maksymalny rozmiar, musi zostać "zsynchronizowany". cel użycia równoczesnego HashMap).

Proszę dać mi znać swoje myśli.

+3

sprawdź rozmiar przed umieszczeniem? – vefthym

+2

w concurrenthashmap podany rozmiar nie jest dokładny. może użyć concurrenthashmap z semaforem zliczającym? –

+1

"nie wiem, w jaki sposób # 2 można zastosować na ConcurrentHashMap bez wpływu na współbieżność" ... Nie rozumiem, dlaczego to będzie problem. Tworzysz opakowanie, które na współbieżnej mapie wprowadza licznik. Aby zsynchronizować dostęp do licznika, należy użyć własnego prymitywu synchronizującego (np. ReentrantLock), aby zminimalizować dodatkowe obciążenie i oddzielić go od synchronizacji współbieżnej mapy. Wtedy wszystko powinno działać dobrze – heorhi

Odpowiedz

6

Ty może zaimplementować mapę delegującą do ConcurrentHashMap, używając semafora liczącego do ograniczenia liczby elementów na mapie. Klasa Semaphore używa zaktualizowanej atomowo wartości int do śledzenia zezwoleń, więc nie poniosłoby to zbyt wiele dodatkowych kosztów.

+2

Używaj 'tryAcquire'' Semafora' przed 'put' i' release' po 'remove', ponieważ nie chcesz blokować. –

2

Możesz zrobić to wszystko samemu, a sam arsenał java może dostarczyć ci tego, czego potrzebujesz, ale zdecydowanie zalecam łatwiejszą i bardziej skalowalną metodologię, ponieważ samodzielne wykonanie tej pracy wymyśliłoby nowe koło. Spróbować jednego z nich w sieciach danych pamięci:

Na przykład w ehcache można osiągnąć to, co chcesz o konfiguracji zbliżonej do:

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

Głównym minusem jest to, że będzie to wolniej o wiele rzędów wielkości. –

+0

Mogę się zgodzić, że tak, ale z drugiej strony należy wybierać optymalne rozwiązania. Niektóre z rozproszonych map skrótów przechowują ponad miliony danych w oddzielnych regionach, a powiązane usługi odpowiadają w dopuszczalnych ramach czasowych. Biorąc to pod uwagę, 10000 jest bardzo małą liczbą. – Pumpkin

+1

Nie sprawdziłem jeszcze szczegółów, ale nie potrzebuję rozproszonego bufora podręcznego. Mogę żyć z prostą mapą hash spełniającą powyższe wymagania. Czy to znaczy, że ConcurrentHashMap z semaforem ma więcej sensu? –

0

Jeśli używasz ConcurrentHashMap, co jest tutaj oczywistym wyborem, użyj wejścia concurrencyLevel do konstruktora, aby zwiększyć przepustowość - to dzieli mapę na wiele stref, aby uniknąć konfliktów put.

+0

Zmiana 'concurrencyLevel' w żaden sposób nie rozwiązuje problemu związanego z tabelą ConcurrentMap o stałym rozmiarze. –

+0

Uzgodnione. Nie rozwiązuje to problemu o stałym rozmiarze ConcurrentMap. –

+0

Zgodził się również ze mną, ale poprawi to współbieżność, co było jego drugim problemem. Warto zauważyć. –

0

Co powiesz na utrzymanie rozmiaru Hashmap przez cały czas, aby zapewnić całkowitą liczbę wstawionych elementów? Możesz użyć AtomicInteger, abyś nie musiał synchronizować/blokować zwykłego int i poświęcić korzyści z używania ConcurrentHashMap.