ConcurrentHashMap. Реализация и особенности

1.

ConcurrentHashMap
Автор:
Абилов Рамиль

2.

План
доклада
Как же появился
ConcurrentHashMap
Реализация и
особенности
Сравнение с
synchronizedMap

3.

1.1 Мир без ConcurrentHashMap
JDK 1.0
HashTable
JDK 1.2
JDK 1.2
HashMap
synchronized
Map
потокобезопасная и
легкая в
использовании
В однопоточной
среде намного
быстрее, чем
обеспечение базовую
синхронизацию,
блокируя всю карту
реализация хэштаблицы
Hashtable.
Позволяет null ключ и
null значение.
при выполнении
любых операций с
ней
Непотокобезопасна

4.

1.2 Причины появления
ConcurrentHashMap
К моменту появления ConcurrentHashMap Java-разработчики
нуждались в следующей реализации хэш-карты:
Потокобезопасность
Отсутствие
блокировок всей
таблицы на время
доступа к ней
Желательно, чтобы
отсутствовали
блокировки таблицы
при выполнении
операции чтения

5.

1.3 Появление ConcurrentHashMap
Таким образом, c JDK 1.2 список вариантов реализации хэш-карт в Java
пополнился ещё двумя способами. Однако эти способы не избавили
разработчиков от появления ConcurrentModificationException.
Для таких объектов, как HashMap , выполнение параллельных операций
не допускается. Поэтому, если мы попытаемся обновить HashMap во
время итерации по нему, мы получим данное исключение. Это также
произойдет при использовании synchronizedMap().
Однако к ConcurrentHashMap это не относится.

6.

2. Реализация и особенности
Элементы карты
Сегменты
Хэш-функция
ConcurrencyLevel

7.

2.1 Элементы карты
В отличие от элементов HashMap,
Entry в ConcurrentHashMap
объявлены как volatile.
*присвоение значения volatile переменной имеет
связь happens-before для последующих чтений из
этой переменной для любых потоков, то есть после
присвоения нового значения переменной все потоки
увидят это новое значение.

8.

2.2 Хэшфункция
Какой хэш-функция была в
HashMap из JDK 1.2:
Версия хэш-функции из
ConcurrentHashMap JDK 1.5:
В чём необходимость усложнения хэш-функции?

9.

2.3
Сегменты
Вот как в карте хранятся элементы:
Карта делится на N различных сегментов
(16 по умолчанию). Каждый сегмент
представляет собой потокобезопасную
таблицу элементов карты.
Между хэш-кодами ключей и
соответствующими им сегментами
устанавливается зависимость на основе
применения к старшим разрядам хэшкода битовой маски.

10.

Что представляет из себя класс сегмента:

11.

2.4.1
ConcurrencyLevel
*Данный параметр влияет на
использование картой памяти и
количество сегментов в карте.
*Важно понимать...
*Количество сегментов
будет выбрано как
ближайшая степень двойки,
большая чем
concurrencyLevel. Ёмкость
каждого сегмента,
соответственно, будет
определяться как отношение
округлённого до ближайшей
большей степени двойки
значения ёмкости карты по
умолчанию, к полученному
количеству сегментов.

12.

2.4.2 Как же выбрать
concurrencyLevel?
*Если лишь один поток будет изменять карту, а остальные
будут производить чтение — рекомендуется использовать
значение 1.
*Необходимо помнить, что resize таблиц для хранения
внутри карты — операция, требующая дополнительного
времени (и, зачастую, выполняемая не быстро).

13.

3.Сравнение с synchronizedMap

14.

Итоги
Карта имеет схожий с hashmap интерфейс взаимодействия
Операции чтения не требуют блокировок и выполняются
параллельно
Операции записи зачастую также могут выполняться
параллельно без блокировок
Элементы карты имеют значение value, объявленное как
volatile

15.

Спасибо за
внимание!
English     Русский Правила