
Технологии Java — явление, сопровождающее нас повсюду, где царствуют современные разработки, электронные устройства любого вида и предназначения. Проще — повсюду, где имеет место программирование, особенно программирование основных компьютеров сети — серверов. Собственно, последнее труднее всего представить сегодня без Java. Этот факт, несомненно, заслуживает того, чтобы о нём говорили много и многие.
За 15 лет своего существования Java обросла множеством деталей, которые полезно знать. Например, от современного программиста, желающего работать у одного из создателей Apache Harmony, требуется разобраться в потокобезопасности обращения к java.util.HashMap
. К Вашему прочтению я предлагаю обзор современных возможностей быстрой синхронизации коллекций, которым, на мой взгляд, во всемирной паутине уделено слишком мало внимания.
Пакет java.util.concurrent
Пакет java.util.concurrent
и его подпакеты добавлены в JDK*, начиная с версии 1.5. Этот пакет содержит в себе массу функциональных возможностей синхронизации параллельных потоков. Исторически, начиная с JDK 1.0, в java.util
коллекции, такие как Vector
и Hashtable
, были явным образом синхронизованы. Сейчас, когда большинство компьютеров стало многоядерными, многих беспокоит, что во время работы одного потока с коллекцией все остальные стоят. Требование сегодняшнего дня: минимум блокировок.
Авторы JDK 1.2 отдали синхронизацию на откуп разработчикам, выбросив синхронизацию, например, из java.util.HashMap
. Разработчики не всегда пользовались открывшимися возможностями грамотно, что приводило к нарушению логики работы и структуры внутренних данных коллекции. Поэтому следующей итерацией разработки стало создание пакета java.util.concurrent
, содержащего классы, эффективно реализующие стандартные модели синхронизации из мира операционных систем и их приложения:
- Исполнители
- Очереди
- Семафоры
- Параллельные коллекции
Подпакеты java.util.concurrent
описывают локи и атомарные операции. В этой статье ознакомимся подробнее с параллельными коллекциями. Прежде всего, нас интересуют потокобезопасные реализации интерфейсов List
и Map
.
ConcurrentHashMap
Данный класс обеспечивает параллельное выполнение множества операций чтения и записи. Достигается это благодаря тому, что во время выполнения перебора коллекции вся таблица не блокируется, а значит в ней остается возможность модификации данных. Таблица делится на число сегментов равное числу одновременно работающих потоков, которые записывают данные. И запись в этом сегменте не влияет на данные остальных ячеек. Итераторы, которые возвращают ConcurrentHashMap.iterator()
, возвращают также каждую запись массива не больше одного раза и не выбрасывают при этом ConcurrentModificationException
. Однако вместе с тем, итераторы ConcurrentHashMap
не гарантируют, что новый элемент попадет в уже созданный итератор или будет удален из него при необходимости. В завершении знакомства с этим классом стоит упомянуть о такой достаточно интересной штуковине, как ReenterantReadWriteLock
. С помощью неё Вы можете сделать любой объект поотокобезопасным по принципу, что чтение данных может производиться несколькими потоками без блокировки, а запись только одним.
CopyOnWriteArraySet и CopyOnWriteList
Ещё два класса в java.util.concurrent
реализируют список и множество. Итераторы этих коллекций перебирают только те элементы, которые были в коллекции ещё при конструировании итератора. Данный класс предназначен для копирования внутренних данных массива при попытке их изменения. По сути, в основе CopyOnWriteArraySet
лежит CopyOnWriteList
с volatile
ссылкой на массив. При записи создается новый массив на единицу больше текущего. Он копируется в новый и ссылка на массив обновляется. То есть, при каждом изменении списка создается его новая копия и работа идет уже в ней. Такая изменяемая ссылка на массив избавляет от необходимости всякий раз копировать список при переборе, или блокировать таблицу. Запись в массив делается с синхронизацией. Чтение записей массива выполняется без синхронизации. CopyOnWriteArrayList
удобно использовать в работе со списками небольших размеров и когда число чтений в разы превышает число записей (вставок или удалений).
*Java Development Kit — инструментарий для работы с Java, включает в себя компилятор, стандартные библиотеки классов Java, утилиты, исполнительную систему JRE, документацию и примеры.
Комментариев нет :
Отправить комментарий