Очередь Майкла и Скотта
Очередь Майкла и Скотта (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 - новый фиктивный элемент
Добавление элемента
Создадим новый узел списка, и добавим его в конец очереди.
def push(x: T):
    newTail = new Node<T>(x, new AtomicReference<Node<T>>(null))
    T.next = newTail //Добавление новой вершины в очередь
    T = T.next //Изменение хвоста списка
Примечания
Источники информации
- Maurice Herliny & Nir Shavit - The Art of Multiprocessor programming, стр 230