2.82M
Категория: ПрограммированиеПрограммирование

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
Отсутствие
Потокобезопасность
блокировок всей
таблицы на время
доступа к ней
Желательно, чтобы
отсутствовали
блокировки таблицы
при выполнении
операции чтения

5.

1.3 Появление ConcurrentHashMap
Таким образом, c JDK 1.2 список вариантов реализации хэш-таблицы в
Java пополнился ещё двумя способами. Однако эти способы не избавили
разработчиков от появления ConcurrentModificationException.
НО данное исключение к ConcurrentHashMap это не относится.

6.

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

7.

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

8.

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

9.

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

10.

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

11.

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

12.

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

13.

3.1 Сравнение с synchronizedMap

14.

3.2 Сравнение с synchronizedMap
ConcurrentHashMap
SynchronizedMap
блокирует отдельные бакеты
блокирует всю мапу
ConcurrentHashMap позволяет
выполнять одновременные операции
чтения и записи
В Synchronized HashMap несколько
потоков не могут одновременно
обращаться к мапе
не генерирует исключение
ConcurrentModificationException
выдает исключение
ConcurrentModificationException
не позволяет вставлять значение null в
качестве ключа или значения
позволяет вставлять значение null в
качестве ключа

15.

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

16.

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