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


148

Яка різниця між використанням класу обгортки SynchronizedMap, на а HashMapта ConcurrentHashMap?

Це просто можливість змінити HashMapчас ітерації ( ConcurrentHashMap)?

Відповіді:


120

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

  1. Кожен метод синхронізується за допомогою блокування об'єктного рівня. Тож способи отримати і поставити на синхронізують придбання блокування.

  2. Блокування всієї колекції - це продуктивні витрати. Хоча одна нитка тримається за замок, жодна інша нитка не може використовувати колекцію.

ConcurrentHashMap була представлена ​​в JDK 5.

  1. Немає блокування на рівні об'єкта, блокування є набагато тоншою деталізацією. Для a ConcurrentHashMap, блоки можуть знаходитися на рівні відра хешмапу.

  2. Ефект блокування нижнього рівня полягає в тому, що ви можете мати одночасних читачів і записувачів, що неможливо для синхронізованих колекцій. Це призводить до набагато більшої масштабованості.

  3. ConcurrentHashMapне кидає a, ConcurrentModificationExceptionякщо один потік намагається змінити його, тоді як інший повторюється над ним.

Ця стаття Java 7: HashMap проти ConcurrentHashMap - це дуже добре прочитане. Настійно рекомендується.


7
Отже, чим відрізняється Hashtableі Synchronized HashMap?
roottraveller

1
Між ConcurrentHashMap та синхронізованою HashMap, яку ви рекомендуєте?
Blunderchips

2
Варто відзначити , що ConcurrentHashMap«S size()результат може втратити свою актуальність. size()дозволяється повернути апроксимацію замість точного підрахунку відповідно до книги "Конкурс Java в практиці". Тож цей метод слід застосовувати обережно.
Андрій Лісун

1
@roottraveller для Hashtable і синхронізованого HashMap stackoverflow.com/questions/8875680/…
Narendra Jaggi

89

Коротка відповідь:

Обидві карти є безпечними потоками реалізації Mapінтерфейсу. ConcurrentHashMapреалізується для підвищення пропускної здатності у випадках, коли очікується висока одночасність.

Стаття Брайана Геца про ідею, що ConcurrentHashMapстоїть, дуже добре прочитана. Настійно рекомендується.


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безпечно для потоків без синхронізації всієї карти. Читання може відбуватися дуже швидко, поки запис робиться за допомогою блокування.


18

Ми можемо досягти безпеки потоку, використовуючи як ConcurrentHashMap, так і синхронізовану Hashmap. Але різниці є дуже багато, якщо подивитися на їх архітектуру.

  1. синхронізована шаш-карта

Він буде підтримувати замок на рівні об'єкта. Отже, якщо ви хочете виконати будь-яку операцію, наприклад, поставити / дістати, то спочатку потрібно придбати замок. У той же час, інші потоки не дозволяють виконувати жодну операцію. Тож одночасно над цим може працювати лише одна нитка. Тож час очікування тут збільшиться. Можна сказати, що продуктивність порівняно низька, якщо ви порівнюєте з ConcurrentHashMap.

  1. ConcurrentHashMap

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

Якщо нитка1 хоче виконати операцію поставлення в сегменті 2, а нитка2 хоче виконати операцію поставлення на сегменті 4, то це дозволено тут. Значить, 16 потоків можуть одночасно виконувати операцію оновлення (поставити / видалити) на ConcurrentHashMap.

Так що часу очікування тут буде менше. Отже, продуктивність порівняно краща за синхронізовану Hashmap.


Дуже приємне пояснення Дякую
amoljdv06

11

Обидві є синхронізованою версією HashMap з різницею в їх основній функціональності та внутрішній структурі.

ConcurrentHashMap складається з внутрішніх сегментів, які концептуально можуть розглядатися як незалежні HashMaps. Усі такі сегменти можуть бути заблоковані окремими потоками у високих паралельних виконаннях. Таким чином, кілька потоків можуть отримати / поставити пари ключових значень з ConcurrentHashMap, не блокуючи / чекаючи один одного. Це реалізовано для підвищення пропускної здатності.

тоді як

Collections.synchronizedMap () , ми отримуємо синхронізовану версію HashMap і доступ до неї блокується. Це означає, що якщо кілька потоків намагаються одночасно отримати доступ до sinkronizedMap, їм буде дозволено синхронізовано отримувати / ставити пари ключових значень.


7

ConcurrentHashMapвикористовує тонкозернистий механізм блокування, відомий як такий, lock strippingщо дозволяє отримати більший ступінь спільного доступу. Завдяки цьому він забезпечує кращу одночасність та масштабованість .

Крім того, ітератори, для ConcurrentHashMapяких повернулися, є досить послідовними, замість того, щоб не швидко проходити техніка, що використовується синхронізованим HashMap.


3

Методи SynchronizedMapутримування блокування на об'єкті, тоді як в ConcurrentHashMapньому існує концепція "блокування смуг", де замість них тримаються відра з вмістом. Таким чином покращилася масштабованість та продуктивність.


2

ConcurrentHashMap:

1) Обидві карти є безпечними для потоків реалізаціями інтерфейсу Map.

2) ConcurrentHashMap реалізується для підвищення пропускної здатності в тих випадках, коли очікується висока конкурентоспроможність.

3) Немає блокування на рівні об'єкта.

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

1) Кожен метод синхронізується за допомогою блокування об'єктного рівня.


1

ConcurrentHashMap дозволяє одночасно мати доступ до даних. Вся карта поділена на сегменти.

Операція читання, тобто. get(Object key)не синхронізується навіть на рівні сегмента.

Але операції запису, тобто. remove(Object key), get(Object key)придбати замок на рівні сегмента. Заблокована лише частина всієї карти, інші потоки все ще можуть читати значення з різних сегментів, крім заблокованої.

SynchronizedMap, з іншого боку, набувають блокування на рівні об'єкта. Усі потоки повинні чекати поточного потоку незалежно від роботи (читання / запис).


1

Простий тест продуктивності для ConcurrentHashMap проти синхронізованого HashMap . Тестовий потік викликає putодин потік і одночасно викликає getтри потоки Map. Як сказав @trshiv, ConcurrentHashMap має більш високу пропускну здатність і швидкість, для читання яких працює без блокування. Результат - коли час роботи закінчується 10^7, ConcurrentHashMap 2xшвидше, ніж синхронізований HashMap.


1

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

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

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

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


0

Відповідно до java doc

Hashtable і Collections.synchronizedMap (новий HashMap ()) синхронізуються. Але ConcurrentHashMap є "одночасним".

Паралельна колекція є безпечною для потоків, але не регулюється одним блокуванням виключення.

У конкретному випадку ConcurrentHashMap, він безпечно дозволяє будь-яку кількість одночасних зчитувань, а також регульовану кількість одночасних записів. "Синхронізовані" класи можуть бути корисні, коли вам потрібно запобігти доступ до колекції за допомогою одного блокування за рахунок біднішої масштабованості.

В інших випадках, коли очікується, що декілька потоків мають доступ до загальної колекції, зазвичай є "одночасними" версіями. І несинхронізовані колекції є кращими, коли будь-які колекції не мають спільного доступу, або доступні лише тоді, коли зберігаються інші блоки.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.