HashMap vs. Współbieżne HashMap vs. SynchronizedMap – Jak można zsynchronizować HashMap w Javie

Opublikowany: 2015-01-29

Crunchify ConcurrentHashMap vs. Przykład zsynchronizowanej mapy HashMap to bardzo potężna struktura danych w Javie. Używamy go codziennie i prawie we wszystkich aplikacjach. Jest kilka przykładów, które napisałem wcześniej: Jak zaimplementować pamięć podręczną Threadsafe, Jak przekonwertować Hashmap na Arraylist?

Użyliśmy Hashmap w obu powyższych przykładach, ale są to dość proste przypadki użycia Hashmap. HashMap is a non-synchronized klasa kolekcji.

Czy masz któreś z poniższych pytań?

  • Jaka jest różnica między ConcurrentHashMap a Collections.synchronizedMap(Map)?
  • Jaka jest różnica między ConcurrentHashMap a Collections.synchronizedMap(Map) pod względem wydajności?
  • ConcurrentHashMap vs Collections.synchronizedMap()
  • Popularne pytania do wywiadów HashMap i ConcurrentHashMap

W tym samouczku omówimy wszystkie powyższe zapytania i wyjaśnimy, why and how możemy zsynchronizować Hashmap?

Czemu?

Obiekt Map to skojarzone kontenery, które przechowują elementy, utworzone przez kombinację unikalnie identyfikującego key i zmapowanej value . Jeśli masz bardzo współbieżną aplikację, w której możesz chcieć zmodyfikować lub odczytać wartość klucza w różnych wątkach, idealnym rozwiązaniem jest użycie Concurrent Hashmap. Najlepszym przykładem jest Producer Consumer, który obsługuje współbieżny odczyt/zapis.

Więc co oznacza mapa bezpieczna dla wątków? Jeśli multiple threads uzyskuje dostęp do mapy skrótów, a co najmniej jeden z wątków modyfikuje mapę strukturalnie, must be synchronized externally , aby uniknąć niespójnego widoku zawartości.

W jaki sposób?

Istnieją dwa sposoby na synchronizację HashMap

  1. Zsynchronizowana metoda Map() z kolekcji Java
  2. Użyj ConcurrentHashMap

WspółbieżnaHashMap

  • Powinieneś używać ConcurrentHashMap, gdy potrzebujesz bardzo wysokiej współbieżności w swoim projekcie.
  • Jest bezpieczny dla wątków bez synchronizacji whole map .
  • Odczyty mogą odbywać się bardzo szybko, podczas gdy zapis odbywa się z blokadą.
  • Nie ma blokowania na poziomie obiektu.
  • Blokowanie jest o wiele drobniejsze na poziomie zasobnika hashmap.
  • ConcurrentHashMap nie zgłasza ConcurrentModificationException , jeśli jeden wątek próbuje go zmodyfikować, podczas gdy inny iteruje nad nim.
  • ConcurrentHashMap używa wielu blokad.

ZsynchronizowanaHashMap

  • Synchronizacja na poziomie obiektu.
  • Każda operacja odczytu/zapisu wymaga uzyskania blokady.
  • Zamykanie całej kolekcji jest kosztem wydajności.
  • Zasadniczo daje to dostęp tylko do jednego wątku na całej mapie i blokuje wszystkie inne wątki.
  • Może to spowodować spory.
  • SynchronizedHashMap zwraca Iterator , który szybko kończy się niepowodzeniem przy równoczesnej modyfikacji.

Przyjrzyjmy się teraz kodowi

  1. Utwórz klasę CrunchifyConcurrentHashMapVsSynchronizedHashMap.java
  2. Utwórz obiekt dla każdego HashTable, SynchronizedMap i CrunchifyConcurrentHashMap
  3. Dodaj i pobierz 500k wpisów z Mapy
  4. Zmierz czas rozpoczęcia i zakończenia oraz czas wyświetlania w milisekundach
  5. Użyjemy ExecutorService do równoległego uruchomienia 5 threads

Oto kod Java:

  • shutdown() oznacza, że ​​usługa executora nie przyjmuje więcej przychodzących zadań.
  • awaitTermination() jest wywoływana po żądaniu zamknięcia.

Dlatego musisz najpierw wyłączyć serviceExecutor, a następnie zablokować i poczekać na zakończenie wątków.

Wynik konsoli Eclipse: