Очередь Майкла и Скотта — различия между версиями
(→Удаление элемента) |
|||
Строка 32: | Строка 32: | ||
'''throw''' new EmptyException() | '''throw''' new EmptyException() | ||
H = H.next | H = H.next | ||
− | return H.data <font color=green>H - новый фиктивный элемент</font> | + | return H.data <font color=green>//H - новый фиктивный элемент</font> |
=== Добавление элемента === | === Добавление элемента === |
Версия 17:39, 1 октября 2018
Эта статья находится в разработке!
Очередь Майкла и Скотта (Michael-Scott Queue) - алгоритм построения lock-free очереди. Впервые был предложен Maged M. Michael и Michael L. Scot в статье [1].
Содержание
Структура очереди
Очередь моделируется с помощью односвязного списка. Каждый элемент списка (
) содержит ссылку на хранимые в нём данные и указатель на следующий элемент списка (который можно менять атомарно).case class Node<T>(val data: T, val next: AtomicReference<Node<T>>)
Если узел
является последним в списке, то его указывает на .Сама очередь состоит из двух указателей: на голову
и на хвост , которые можно менять атомарно. Удаление из очереди происходит со стороны головы, добавление - со стороны хвоста.Узел списка, на который указывает
, является фиктивным (dummy). Данные, хранимые в этом узле, не имеют значения. Изначально очередь состоит из одного dummy-элемента, на который указывают и .class Queue<T> dummy = new Node<T>(null, new AtomicReference<Node>(null)) head = new AtomicReference<Node<T>>(dummy) tail = new AtomicReference<Node<T>>(dummy)
// TODO; картинка
Будем поддерживать следующий инвариант: в нашей очереди
указывает на узел, находящийся не правее узла, на который указываетИдея реализации
Удаление элемента
Для удаления элемента необходимо переместить указатель
на следующую в списке вершину.def pop(): T if (H.next == null): throw new EmptyException() H = H.next return H.data //H - новый фиктивный элемент
Добавление элемента
Примечания
Источники информации
- Maurice Herliny & Nir Shavit - The Art of Multiprocessor programming, стр 230