ConcurrentHashMap против синхронизированного HashMap

149

В чем разница между использованием класса-обёртки SynchronizedMap, а HashMapи ConcurrentHashMap?

Это просто возможность изменить HashMapвремя итерации ( ConcurrentHashMap)?

hello_world_infinity
источник

Ответы:

121

Синхронизировано HashMap:

  1. Каждый метод синхронизируется с помощью блокировки уровня объекта. Таким образом, методы get и put для synchMap получают блокировку.

  2. Блокировка всей коллекции - накладные расходы. Пока один поток удерживает блокировку, другой поток не может использовать коллекцию.

ConcurrentHashMap был введен в JDK 5.

  1. На уровне объекта блокировки нет, Блокировка гораздо более детализирована. Для a ConcurrentHashMapблокировки могут быть на уровне сегмента hashmap.

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

  3. ConcurrentHashMapне выдает, ConcurrentModificationExceptionесли один поток пытается изменить его, в то время как другой перебирает его.

Эта статья Java 7: HashMap vs ConcurrentHashMap очень хорошо читается. Настоятельно рекомендуется.

Joey.zhgw
источник
7
Так в чем же разница между Hashtableи Synchronized HashMap?
roottraveller
1
Какой из них вы рекомендуете между ConcurrentHashMap и Synchronized HashMap?
Промахи
2
Стоит отметить , что ConcurrentHashMap«S size()результат может устареть. size()разрешено возвращать приближение вместо точного подсчета в соответствии с книгой "Java Concurrency in Practice". Поэтому этот метод следует использовать осторожно.
Андрей Лисун
1
@roottraveller для Hashtable и синхронизированной HashMap stackoverflow.com/questions/8875680/…
Нарендра Джагги
89

Краткий ответ:

Обе карты являются поточно-ориентированными реализациями Mapинтерфейса. ConcurrentHashMapреализован для более высокой пропускной способности в случаях, когда ожидается высокий параллелизм.

Статья Брайана Гетца об этой идее ConcurrentHashMapочень хорошо читается. Настоятельно рекомендуется.

trshiv
источник
1
Что это тогда? HashMap: обратите внимание, что эта реализация не синхронизирована для предотвращения случайного несинхронизированного доступа к карте: Map m = Collections.synchronizedMap(new HashMap(...)); docs.oracle.com/javase/7/docs/api/java/util/HashMap.html
X-HuMan
5
«Статья Брайана Гетца ... очень хорошо читается». И тем более его книга «Параллелизм Java на практике».
Алексей Федулов,
31

ConcurrentHashMapявляется потокобезопасным без синхронизации всей карты. Чтение может происходить очень быстро, в то время как запись выполняется с блокировкой.

fastcodejava
источник
18

Мы можем обеспечить безопасность потоков, используя как ConcurrentHashMap, так и synchronizedHashmap. Но есть большая разница, если вы посмотрите на их архитектуру.

  1. synchronisedHashmap

Он будет поддерживать блокировку на уровне объекта. Поэтому, если вы хотите выполнить какую-либо операцию, такую ​​как put / get, вам нужно сначала получить блокировку. В то же время другим потокам не разрешается выполнять какие-либо операции. Таким образом, только один поток может работать с этим. Так что время ожидания здесь увеличится. Можно сказать, что производительность относительно низкая, если сравнивать с ConcurrentHashMap.

  1. ConcurrentHashMap

Он будет поддерживать блокировку на уровне сегмента. Он имеет 16 сегментов и поддерживает уровень параллелизма как 16 по умолчанию. Таким образом, одновременно 16 потоков могут работать с ConcurrentHashMap. Более того, операция чтения не требует блокировки. Таким образом, любое количество потоков может выполнить операцию get.

Если thread1 хочет выполнить операцию put в сегменте 2, а thread2 хочет выполнить операцию put в сегменте 4, то это разрешено здесь. Значит, 16 потоков могут одновременно выполнять операцию обновления (вставки / удаления) в ConcurrentHashMap.

Так что время ожидания здесь будет меньше. Следовательно, производительность относительно лучше, чем synchronizedHashmap.

Суманта Варада
источник
Очень хорошее объяснение Большое спасибо
amoljdv06
11

Оба являются синхронизированной версией HashMap, с разницей в их основной функциональности и внутренней структуре.

ConcurrentHashMap состоит из внутренних сегментов, которые концептуально можно рассматривать как независимые HashMaps. Все такие сегменты могут быть заблокированы отдельными потоками при одновременном выполнении. Таким образом, несколько потоков могут получать / помещать пары ключ-значение из ConcurrentHashMap, не блокируя и не ожидая друг друга. Это реализовано для повышения пропускной способности.

в то время как

Collections.synchronizedMap () , мы получаем синхронизированную версию HashMap, доступ к которой осуществляется блокирующим образом. Это означает, что если несколько потоков попытаются получить доступ к synchronizedMap одновременно, им будет разрешено получать / помещать пары ключ-значение по одной синхронно.

Ashraf.Shk786
источник
7

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

Кроме того, возвращаемые значения для итераторов ConcurrentHashMapявляются слабосогласованными вместо метода быстрого отказа, используемого Synchronized HashMap.

rai.skumar
источник
3

Методы SynchronizedMapудерживают блокировку на объекте, в то время как ConcurrentHashMapесть понятие «чередование блокировок», когда вместо блокировок удерживаются блоки содержимого. Таким образом улучшается масштабируемость и производительность.

Renukeswar
источник
2

ConcurrentHashMap:

1) Обе карты являются поточно-ориентированными реализациями интерфейса Map.

2) ConcurrentHashMap реализован для более высокой пропускной способности в тех случаях, когда ожидается высокий параллелизм.

3) Нет блокировки на уровне объекта.

Синхронизированная карта хеша:

1) Каждый метод синхронизируется с помощью блокировки уровня объекта.

NarayanaReddy
источник
1

ConcurrentHashMap обеспечивает одновременный доступ к данным. Вся карта делится на сегменты.

Операция чтения т.е. get(Object key)не синхронизируется даже на уровне сегмента.

Но операции записи т.е. remove(Object key), get(Object key)получить блокировку на уровне сегмента. Только часть всей карты заблокирована, другие потоки все еще могут читать значения из различных сегментов, кроме заблокированного.

SynchronizedMap, с другой стороны, получает блокировку на уровне объекта. Все потоки должны ждать текущего потока независимо от операции (чтение / запись).

дешевое вино
источник
1

Простой тест производительности для ConcurrentHashMap против Synchronized HashMap . Тестовый поток вызывает putв одном потоке и одновременно getв трех потоках Map. Как сказал @trshiv, ConcurrentHashMap имеет более высокую пропускную способность и скорость для операций чтения без блокировки. В результате, когда время работы истекло 10^7, ConcurrentHashMap работает 2xбыстрее, чем Synchronized HashMap.

liaoming
источник
1

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

SynchronizedMapполучает блокировку для всего экземпляра Map, в то время ConcurrentHashMapкак экземпляр Map разделяется на несколько сегментов, и блокировка выполняется для них.

введите описание изображения здесь

введите описание изображения здесь

Джоби Уилсон Мэтьюз
источник
0

Согласно документу Java

Hashtable и Collections.synchronizedMap (новый HashMap ()) синхронизируются. Но ConcurrentHashMap является «одновременным».

Параллельная коллекция является поточно-ориентированной, но не управляется одной блокировкой исключения.

В конкретном случае ConcurrentHashMap он безопасно разрешает любое количество одновременных операций чтения, а также настраиваемое количество одновременных операций записи. «Синхронизированные» классы могут быть полезны, когда вам нужно запретить любой доступ к коллекции через одну блокировку за счет более низкой масштабируемости.

В других случаях, когда ожидается, что несколько потоков получат доступ к общей коллекции, «параллельные» версии обычно предпочтительнее. А несинхронизированные коллекции предпочтительнее, когда либо коллекции не являются общими, либо доступны только при удержании других блокировок.

Pramod
источник