Домой Учебники по Java и J2EE HashMap Vs. ConcurrentHashMap Vs. SynchronizedMap — Как HashMap может быть синхронизирован в...

HashMap Vs. ConcurrentHashMap Vs. SynchronizedMap — Как HashMap может быть синхронизирован в Java

1105
0

HashMap это очень мощная структура данных в Java. Мы используем его каждый день и почти во всех приложениях. Есть довольно много примеров, которые я написал ранее о том, как реализовать потокобезопасный кеш , как конвертировать Hashmap в Arraylist ?

Мы использовали Hashmap в обоих приведенных выше примерах, но это довольно простые случаи использования Hashmap. HashMap is a non-synchronized коллекционный класс.

Есть ли у вас какие-либо вопросы ниже?

  • В чем разница между ConcurrentHashMap и Collections.synchronizedMap (Map)?
  • В чем разница между ConcurrentHashMap и Collections.synchronizedMap (Map) с точки зрения производительности ?
  • ConcurrentHashMap против Collections.synchronizedMap ()
  • Популярные вопросы интервью HashMap и ConcurrentHashMap

В этом уроке мы рассмотрим все вышеперечисленные вопросы и причины why and how мы могли бы синхронизировать Hashmap?

Зачем?

Объект Map представляет собой ассоциативные контейнеры, в которых хранятся элементы, образованные комбинацией уникальной идентификации key и нанесенный на карту value , Если у вас есть приложение с высокой степенью параллелизма, в котором вы можете изменить или прочитать значение ключа в разных потоках, тогда идеально использовать Concurrent Hashmap. Лучшим примером является Producer Consumer, который обрабатывает одновременное чтение / запись.

Так что же означает поточно-ориентированная карта? Если multiple threads получить доступ к хеш-карте одновременно, и по крайней мере один из потоков изменяет карту структурно, он must be synchronized externally чтобы избежать противоречивого просмотра содержимого.

Как?

Есть два способа синхронизировать HashMap

  1. Метод Java Collections synchronizedMap ()
  2. Используйте ConcurrentHashMap
HashMap Vs. synchronizedMap Vs. ConcurrentHashMap

1
2
3
4
5
6
7
8
//Хеш-таблица
Карта < Строка , Строка > NormalMap знак равно новый Hashtable < String , Строка > ( ) ;
// synchronizedMap
synchronizedHashMap знак равно Коллекции . synchronizedMap ( новый HashMap < String , Строка > ( ) ) ;
// ConcurrentHashMap
ConcurrentHashMap знак равно новый ConcurrentHashMap < String , Строка > ( ) ;

ConcurrentHashMap

  • Вы должны использовать ConcurrentHashMap, когда вам нужен очень высокий параллелизм в вашем проекте.
  • Поток безопасен без синхронизации whole map ,
  • Чтение может происходить очень быстро, в то время как запись выполняется с блокировкой.
  • На уровне объекта нет блокировки.
  • Блокировка на более тонкой детализации на уровне сегмента хэш-карты.
  • ConcurrentHashMap не создает ConcurrentModificationException если один поток пытается изменить его, в то время как другой перебирает его.
  • ConcurrentHashMap использует множество блокировок.

SynchronizedHashMap

  • Синхронизация на уровне объекта .
  • Каждая операция чтения / записи должна получить блокировку.
  • Блокировка всей коллекции — накладные расходы.
  • По сути, это дает доступ только одному потоку ко всей карте и блокирует все остальные потоки.
  • Это может вызвать раздор.
  • SynchronizedHashMap возвращает Iterator , который терпит неудачу при одновременной модификации.

Теперь давайте посмотрим на код

  1. Создать класс CrunchifyConcurrentHashMapVsSynchronizedHashMap.java
  2. Создать объект для каждого HashTable, SynchronizedMap и CrunchifyConcurrentHashMap
  3. Добавить и получить 500 тыс. Записей с карты
  4. Измерьте время начала и окончания и время отображения в миллисекундах
  5. Мы будем использовать ExecutorService для запуска 5 threads в параллели

Вот код Java:

CrunchifyConcurrentHashMapVsSynchronizedMap.java

Джава
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
пакет crunchify. ком . учебные пособия ;
Импортировать Java. Util. Коллекции ;
Импортировать Java. Util. HashMap ;
Импортировать Java. Util. Hashtable ;
Импортировать Java. Util. Карта ;
Импортировать Java. Util. одновременно. ConcurrentHashMap ;
Импортировать Java. Util. одновременно. ExecutorService ;
Импортировать Java. Util. одновременно. Исполнители ;
Импортировать Java. Util. одновременно. TimeUnit ;
/ **
* @author Crunchify.com
*
* /
общественности учебный класс CrunchifyConcurrentHashMapVsSynchronizedMap {
общественности окончательный статический ИНТ THREAD_POOL_SIZE знак равно 5 ;
общественности статический Карта < Строка , Целое число > crunchifyHashTableObject знак равно ноль ;
общественности статический Карта < Строка , Целое число > crunchifySynchronizedMapObject знак равно ноль ;
общественности статический Карта < Строка , Целое число > crunchifyConcurrentHashMapObject знак равно ноль ;
общественности статический недействительным main ( Строка [ ] аргументы ) бросает InterruptedException {
// Тест с Hashtable объектом
crunchifyHashTableObject знак равно новый Hashtable < String , Целое число > ( ) ;
crunchifyPerformTest ( crunchifyHashTableObject ) ;
// Тестирование с объектом synchronizedMap
crunchifySynchronizedMapObject знак равно Коллекции . synchronizedMap ( новый HashMap < String , Целое число > ( ) ) ;
crunchifyPerformTest ( crunchifySynchronizedMapObject ) ;
// Тест с объектом ConcurrentHashMap
crunchifyConcurrentHashMapObject знак равно новый ConcurrentHashMap < String , Целое число > ( ) ;
crunchifyPerformTest ( crunchifyConcurrentHashMapObject ) ;
}
общественности статический недействительным crunchifyPerformTest ( окончательный Карта < Строка , Целое число > crunchifyThreads ) бросает InterruptedException {
Система. вне. println ( «Тест начался для:» + crunchifyThreads . getClass ( ) ) ;
долго среднее время знак равно 0 ;
за ( int я знак равно 0 ; я < 5 ; я ++ ) {
долго начальное время знак равно Система. nanoTime ( ) ;
ExecutorService crunchifyExServer знак равно Исполнители . newFixedThreadPool (THREAD_POOL_SIZE);
за ( int J знак равно 0 ; J < THREAD_POOL_SIZE ; j ++ ) {
crunchifyExServer . выполнить ( новый Runnable ( ) {
@SuppressWarnings ( «не используется» )
@Override
общественности недействительным запустить ( ) {
за ( int я знак равно 0 ; я < 500000 ; я ++ ) {
целое число crunchifyRandomNumber знак равно ( int ) Математика ceil ( Math . random ( ) * 550000 ) ;
// Получить значение. Мы его нигде не используем
целое число crunchifyValue знак равно crunchifyThreads . get ( String . valueOf ( crunchifyRandomNumber ) ) ;
// положить значение
crunchifyThreads . put ( String . valueOf ( crunchifyRandomNumber ) , crunchifyRandomNumber ) ;
}
}
} ) ;
}
// Инициирует упорядоченное отключение, при котором выполняются ранее отправленные задачи, но новые задачи не принимаются. мольба
// не имеет никакого дополнительного эффекта, если он уже выключен.
// Этот метод не ожидает завершения выполнения ранее представленных задач. Используйте awaitTermination, чтобы сделать это.
crunchifyExServer . выключение ( ) ;
// Блокирует до тех пор, пока все задачи не завершат выполнение после запроса на выключение, или не истечет время ожидания, или текущий поток
// прерывается, в зависимости от того, что произойдет первым.
crunchifyExServer . awaitTermination ( Long . MAX_VALUE , TimeUnit . ДНИ ) ;
долго entTime знак равно Система. nanoTime ( ) ;
долго общее время знак равно ( entTime startTime ) / 1000000L ;
среднее время + = totalTime ;
Система. вне. println ( 500K введено добавлено / получено в + общее время + мс ) ;
}
Система. вне. println ( «Для» + crunchifyThreads . getClass ( ) + среднее время + среднее время / 5 + ms / n ) ;
}
}
  • shutdown() означает, что служба исполнителя не принимает больше входящих задач.
  • awaitTermination() вызывается после запроса на отключение.
ЧИТАТЬ ТАКЖЕ:  Пример URL-адреса Java: получение текста с URL-адреса - отправка HTTP-запроса GET / POST в Java

И, следовательно, вам необходимо сначала закрыть serviceExecutor, а затем заблокировать и дождаться завершения потоков.

Eclipse Console Результат:

Результат

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Тест начался для : учебный класс Java. Util. Хеш-таблица
500K entried добавлено / извлекаться в 1832 Миз
500K entried добавлено / извлекаться в 1723 Миз
500K entried добавлено / извлекаться в 1782 Миз
500K entried добавлено / извлекаться в 1607 Миз
500K entried добавлено / извлекаться в 1851 Миз
За учебный класс Java. Util. Hashtable среднее время 1759 Миз
Тест начался для : учебный класс Java. Util. Коллекции $ SynchronizedMap
500K entried добавлено / извлекаться в 1923 Миз
500K entried добавлено / извлекаться в 2032 Миз
500K entried добавлено / извлекаться в 1621 Миз
500K entried добавлено / извлекаться в 1833 Миз
500K entried добавлено / извлекаться в 2048 Миз
За учебный класс Java. Util. Коллекции $ SynchronizedMap среднее время является 1891 Миз
Тест начался для : учебный класс Java. Util. одновременно. ConcurrentHashMap
500K entried добавлено / извлекаться в 1068 Миз
500K entried добавлено / извлекаться в 1029 Миз
500K entried добавлено / извлекаться в 1165 Миз
500K entried добавлено / извлекаться в 840 Миз
500K entried добавлено / извлекаться в 1017 Миз
За учебный класс Java. Util. одновременно. ConcurrentHashMap среднее время +1023 Миз
HashMap Vs. ConcurrentHashMap Vs. SynchronizedMap — Как HashMap может быть синхронизирован в Java

0.00 (0%) 0 votes

ОСТАВЬТЕ ОТВЕТ

Пожалуйста, введите ваш комментарий!
пожалуйста, введите ваше имя здесь