Подтвердить что ты не робот

Как работает ConcurrentHashMap внутри?

Я читал официальную документацию Oracle о Concurrency в Java, и мне было интересно узнать, какая разница между Collection, возвращаемой

public static <T> Collection<T> synchronizedCollection(Collection<T> c);

и используя, например, <

ConcurrentHashMap. Я предполагаю, что использую synchronizedCollection(Collection<T> c) на HashMap. Я знаю, что в общем случае синхронизированная коллекция по существу является просто декоратором для моего HashMap, поэтому очевидно, что ConcurrentHashMap имеет что-то другое в своих внутренних элементах. У вас есть информация об этих деталях реализации?

Изменить: я понял, что исходный код общедоступен: ConcurrentHashMap.java

4b9b3361

Ответ 1

Я бы прочитал источник ConcurrentHashMap, поскольку он довольно сложный в деталях. Короче говоря,

  • Несколько разделов, которые можно заблокировать независимо. (По умолчанию 16)
  • Использование одновременных операций блокировки для безопасности потоков вместо синхронизации.
  • Имеет потокобезопасные итераторы. Итераторы synchronizedCollection не являются потокобезопасными.
  • Не выставляет внутренние блокировки. synchronizedCollection делает.

Ответ 2

ConcurrentHashMap очень похож на класс java.util.HashTable, за исключением того, что ConcurrentHashMap предлагает лучше concurrency, чем HashTable или synchronizedMap. ConcurrentHashMap не блокирует карту, пока вы читаете ее. Кроме того, ConcurrentHashMap не блокирует все Map при записи на него. Он блокирует только часть Map, которая записывается внутри, внутри.

Другое отличие состоит в том, что ConcurrentHashMap не бросает ConcurrentModificationException, если при повторении it ConcurrentHashMap изменяется. Iterator не предназначен для использования более чем одним потоком, хотя synchronizedMap может бросать ConcurrentModificationException

Ответ 3

Это статья, которая помогла мне понять ее Почему ConcurrentHashMap лучше, чем Hashtable, и так же хорош, как HashMap

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

Здесь вы можете выполнить ConcurrentHashMaps. Они предлагают все функции от Hashtable с производительностью, почти такой же хорошей, как HashMap. ConcurrentHashMaps делают это с помощью очень простого механизма. Вместо широкоугольной карты, коллекция поддерживает список из 16 блокировки по умолчанию, каждый из которых используется для защиты (или блокировки) одного ведро карты. Это эффективно означает, что 16 потоков могут изменять сбор за один раз (пока они все работают над разные ведра). Infact нет операции, выполняемой этим которая блокирует всю карту. Уровень concurrencyколлекции, количество потоков, которые могут изменять его одновременно без блокировки, может быть увеличена. Однако большее число означает больше накладные расходы на сохранение этого списка блокировок.

Ответ 4

"Проблемы масштабируемости" для Hashtable присутствуют точно так же в Collections.synchronizedMap(Map) - они используют очень простую синхронизацию, а это означает, что только один поток может одновременно получить доступ к карте.

Это не большая проблема, когда у вас есть простые вставки и поиск (если вы не делаете это очень интенсивно), но становится большой проблемой, когда вам нужно перебирать всю карту, что может занять много времени для большой Карта - в то время как один поток делает это, все остальные должны ждать, хотят ли они вставлять или искать что-либо.

ConcurrentHashMap использует очень сложные методы для уменьшения необходимости синхронизации и обеспечения параллельного доступа для чтения несколькими потоками без синхронизации и, что более важно, предоставляет Итератор, который не требует синхронизации и даже позволяет изменять карту во время взаимодействия ( хотя он не гарантирует, будут ли возвращены элементы, вставленные во время итерации).

Ответ 5

Возвращаемое synchronizedCollection() - это объект, все методы которого синхронизированы по этому вопросу, поэтому все параллельные операции над такой оболочкой сериализуются. ConcurrentHashMap - это действительно параллельный контейнер с мелкозернистой блокировкой, оптимизированный, чтобы держать конкуренцию как можно ниже. Посмотрите на исходный код, и вы увидите, что внутри.

Ответ 6

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