2013-04-19 3 views
10

Я пытаюсь найти ответ на них, но не могу найти его в Google или в документах Java.ConcurrentHashMap блокировки чтения и записи

Случай 1: в ConcurrentHashMap, предположим, что нить t1 читает из сегмента п, и в то же другом потоке t2 хотите написать на же сегменте п:

Вопрос 1: будут ли эти две операции выполняться один за другим или они будут выполняться одновременно?


Случай 2: в ConcurrentHashMap, предположим, что поточно t1 пишет на сегменте п, и в то же другой поток t2 хотите читать из же сегмента п,

Вопрос 2: будут ли эти две операции выполняться один за другим или они будут выполняться одновременно?

+0

hi..highlighted вопросы –

+0

Итак, что вы имеете в виду между ConcurrentHashMap и ReadWriteLock? –

ответ

17

Я думаю JavaDoc ответов оба ваши вопросы:

операцию выборки (включая get-), как правило, не блокирует, поэтому может перекрытия с операциями обновления (в том числе на место и удалить). Retrievals отражают результаты последних завершенных операций обновления , удерживающих их начало. Для совокупных операций, таких как putAll и , четкие, одновременные изъятия могут отражать вставку или удаление только некоторых записей.

сегменты предназначены для операций обновления:

Допустимых параллельности между операциями обновления руководствуются необязательного concurrencyLevel аргумента конструктора (по умолчанию 16), который используется в качестве подсказки для внутренней проклейки.

Таким образом, чтение не блокируется (оно реализовано как чтение изменчивых переменных). Записи могут блокировать друг друга, если они пишут в том же сегменте.

+2

Короче говоря, если сегмент обновлен, а какой-то другой поток хочет его прочитать, он сможет читать, но получит последнее обновленное значение (а не текущее/незавершенное значение), правильно? –

+0

@ Naroji Да, либо до обновления, либо после обновления, зависит от возможности совпадения операций обновления и чтения. Но не что-то смешанное/поврежденное. – kan

+0

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

0

Согласно документации ConcurrentHashMap Oracle,

Конструктор ConcurrentHashMap выглядит следующим образом:

общественного ConcurrentHashMap (INT initialCapacity, всплывают loadFactor, внутр concurrencyLevel)

Таким образом, выше линии создает новую, пустую карту с указанной начальной мощностью, коэффициентом загрузки и уровнем параллелизма. где Важные параметры, которые следует учитывать от ConcurrentHashMap Конструктора:

  • initialCapacity - начальная емкость. Реализация выполняет внутренний размер для размещения этого множества элементов.
  • concurrencyLevel - оценочное число одновременных обновлений потоков. Реализация выполняет внутреннюю калибровку, чтобы попытаться разместить это многопоточное число .

В ConcurrentHashMap Api вы найдете следующие константы.

  • статический окончательный int DEFAULT_INITIAL_CAPACITY = 16;
  • статический окончательный int DEFAULT_CONCURRENCY_LEVEL = 16;

Параметры начальной емкости и параметры уровня параллелирования конструктора ConcurrentHashMap (или объекта) по умолчанию установлены 16.

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

Операции поиска (включая получение) обычно не блокируются. В этом случае он использует концепцию изменчивости., поэтому могут перекрываться с операциями обновления (включая put и remove). Retrievals отражают результаты последних завершенных операций по обновлению с их началом.

Разрешенный параллелизм между операциями обновления управляется необязательным аргументом конструктора concurrencyLevel (по умолчанию 16), который используется как подсказка для внутреннего размера. Таблица внутренне разделена, чтобы попытаться разрешить указанное количество одновременных обновлений без конкуренции. Поскольку размещение в хэш-таблицах по сути является случайным, фактический параллелизм будет отличаться. В идеале вы должны выбрать значение для размещения столько потоков, сколько когда-либо одновременно измените таблицу. Использование значительно более высокой ценности, чем вам нужно, может тратить пространство и время, а значительно меньшее значение может привести к конфликту с потоком.

Надеюсь, это поможет!

Смежные вопросы