Обзор синхронных контейнеров и параллельных контейнеров

Java

Что такое контейнер синхронизации?

Контейнер synchronized изменяет контейнер с помощью ключевого слова synchronized, чтобы гарантировать, что только один поток использует контейнер одновременно, что делает поток контейнера безопасным. Synchronized означает синхронизацию, что выражается в превращении многопоточности в последовательное ожидание выполнения. (Но обратите внимание, что составные операции не могут гарантировать потокобезопасность. Например: поток A получает хвостовой узел на первом шаге и добавляет 1 к значению хвостового узла на втором шаге, но когда поток A завершает выполнение первого шага, поток B удаляет его После хвостового узла будет сообщен нулевой указатель, когда поток A выполнит второй шаг)

Что такое параллельный контейнер?

Параллельный контейнер позволяет нескольким потокам использовать контейнер одновременно и обеспечивает безопасность потоков. Чтобы максимально улучшить параллелизм, Java Concurrency Toolkit использует различные методы оптимизации для повышения эффективности выполнения параллельных контейнеров. и сегментные замки.

Контейнер синхронизации

1.Vector

Vector реализует интерфейс List подобно ArrayList, и его различные операции с массивами такие же, как у ArrayList, с той лишь разницей, что Vertor использует synchronized для изменения всех методов, которые могут быть небезопасными для потоков.

2.Stack

Stack является подклассом Vertor, и Stack реализует стек в порядке поступления. Все операции, такие как извлечение стека и стекирование, синхронизированы.

3.HashTable

HashTable реализует интерфейс Map, а реализуемые им функции в основном такие же, как у HashMap (HashTable не может хранить null, а как ключи, так и значения HashMap могут хранить null). Разница в том, что HashTable использует synchronized для изменения метода.

4. Класс синхронизированной коллекции, предоставляемый Collections

  • List list = Collections.synchronizedList(new ArrayList());
  • Set set = Collections.synchronizedSet(new HashSet());
  • Map map = Collections.synchronizedMap(new HashMap());

По сути, вышеперечисленные три контейнера — это Коллекции, которые добавляют к исходной операции синхронизированную синхронизацию через режим прокси. Степень детализации синхронизации для synchronized слишком велика, что приводит к низкой эффективности многопоточной обработки. Поэтому в JDK1.5 был запущен concurrent-контейнер под concurrent-пакетом для решения проблемы низкой эффективности обработки контейнера при многопоточности.

параллельный контейнер

1.CopyOnWriteArrayList

CopyOnWriteArrayList эквивалентен реализации потокобезопасного ArrayList.Его механизм заключается в копировании массива копирования при выполнении операции записи в контейнер и присвоении ссылки на массив копирования контейнеру после завершения операции. Нижний уровень — обеспечить синхронизацию через ReentrantLock. Но он жертвует высокой эффективностью параллелизма контейнера (старые данные считываются во время копирования), жертвуя согласованностью контейнера. Поэтому его нельзя использовать в сценариях, требующих строгой согласованности.

2.CopyOnWriteArraySet

CopyOnWriteArraySet имеет тот же принцип, что и CopyOnWriteArrayList, это коллекция Set, которая реализует механизм CopyOnWrite.

3.ConcurrentHashMap

CONCURRENTASHMAP эквивалентно реализовать безопасный поток Hashmap. Ключи неупорядочены, и ни одно ключ, ни ценность не может быть нулевым. Перед JDK8 CONCURRENTHASHMAP принял механизм блокировки сегмента для повышения эффективности параллелизма и необходима только для блокировки при работе пары ключа-значений одного и того же сегмента. После JDK8 механизм сегментации блокировки был заброшен, и вместо этого использовался алгоритм CAS.

4.ConcurrentSkipListMap

ConcurrentSkipListMap эквивалентен реализации потокобезопасного TreeMap. Ключи упорядочены, и ни ключ, ни значение не могут быть нулевыми. Он использует механизм таблицы прыжков для замены красно-черного дерева. Почему бы не продолжать использовать красно-черные деревья? Поскольку красно-черное дерево необходимо поворачивать и корректировать при вставке или удалении узлов, степень детализации, которую необходимо контролировать, велика. Таблица переходов использует связанный список и использует механизм CAS без блокировки для достижения высокой безопасности параллельных потоков.

5.ConcurrentSkipListSet

ConcurrentSkipListSet работает по тому же принципу, что и ConcurrentSkipListMap: это TreeSet, реализующий высокий уровень параллелизма и потокобезопасности.

Тип очереди

тип блокировки

1.ArrayBlockingQueue

ArrayBlockingQueue — это потокобезопасная очередь с ограниченной блокировкой, реализованная с использованием массивов. Продолжение добавления элементов в полную очередь приведет к блокировке текущего потока. Получение элемента из пустой очереди приведет к блокировке текущего потока. ReentrantLock используется для обеспечения безопасности потоков в параллельных ситуациях.

2.LinkedBlockingQueue

LinkedBlockingQueue — это произвольная (фактически ограниченная) очередь блокировки FIFO на основе односвязного списка. Операции доступа и удаления выполняются в начале очереди, а операции добавления выполняются в хвосте очереди, и они защищены разными блокировками.Только в операциях, которые могут включать несколько узлов, две блокировки блокируются на в то же время.

3.PriorityBlockingQueue

PriorityBlockingQueue — неограниченная очередь блокировки, поддерживающая приоритет. По умолчанию элементы сортируются в естественном порядке возрастания. Вы также можете настроить класс для реализации метода compareTo(), чтобы указать правила упорядочения элементов,

4.DelayQueue

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

5.SynchronousQueue

SynchronousQueue не имеет пропускной способности. Это блокирующая очередь, которая не хранит элементы. Она будет напрямую доставлять элементы потребителям. Прежде чем добавлять новые элементы, она должна дождаться использования добавленных в очередь элементов. Эквивалент конвейерной ленты с пропускной способностью 1.

6.LinkedTransferQueue

LinkedTransferQueue — неограниченная очередь блокировки передачи, состоящая из связанных списков. Он сочетает в себе преимущества ConcurrentLinkedQueue, SynchronousQueue, LinkedBlockingQueue и так далее. Конкретный механизм более сложен.

7.LinkedBlockingDeque

LinkedBlockingDeque — это двунаправленная очередь блокировки, состоящая из структуры связанного списка. Так называемая двусторонняя очередь относится к вставке и удалению элементов с обоих концов очереди.

неблокирующий

1.ConcurrentLinkedQueue

ConcurrentLinkedQueue — это потокобезопасная неограниченная неблокирующая очередь. Базовая структура данных реализована с использованием односвязного списка. Операции постановки в очередь и удаления из очереди используют CAS, о котором мы часто упоминаем, для обеспечения безопасности потоков.

Уровень автора ограничен, если есть ошибки прошу прокомментировать и поправить меня.

Перейдите на мой личный блог vc2x.com