<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=185.22.181.139&amp;*</id>
		<title>Викиконспекты - Вклад участника [ru]</title>
		<link rel="self" type="application/atom+xml" href="http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=185.22.181.139&amp;*"/>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/185.22.181.139"/>
		<updated>2026-06-11T18:40:58Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D1%8C_%D0%9C%D0%B0%D0%B9%D0%BA%D0%BB%D0%B0_%D0%B8_%D0%A1%D0%BA%D0%BE%D1%82%D1%82%D0%B0&amp;diff=66359</id>
		<title>Очередь Майкла и Скотта</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D1%8C_%D0%9C%D0%B0%D0%B9%D0%BA%D0%BB%D0%B0_%D0%B8_%D0%A1%D0%BA%D0%BE%D1%82%D1%82%D0%B0&amp;diff=66359"/>
				<updated>2018-10-01T16:22:01Z</updated>
		
		<summary type="html">&lt;p&gt;185.22.181.139: /* Описание проблемы */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В разработке}}&lt;br /&gt;
'''Очередь Майкла и Скотта''' ''(Michael-Scott Queue)'' - алгоритм построения lock-free очереди. Впервые был предложен Maged M. Michael и  Michael L. Scot в статье &amp;lt;ref&amp;gt;[http://www.cs.rochester.edu/~scott/papers/1996_PODC_queues.pdf? Simple, Fast, and Practical Non-Blocking and BlockingConcurrent Queue Algorithms]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
== Структура очереди ==&lt;br /&gt;
&lt;br /&gt;
Очередь моделируется с помощью односвязного списка. Каждый элемент списка (&amp;lt;tex&amp;gt;Node&amp;lt;/tex&amp;gt;) содержит ссылку на хранимые в нём данные и указатель на следующий элемент списка (который можно менять атомарно).&lt;br /&gt;
&lt;br /&gt;
 '''case class''' Node('''val''' data: '''Int''', '''val''' next: AtomicReference&amp;lt;Node&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Если узел &amp;lt;tex&amp;gt;node&amp;lt;/tex&amp;gt; является последним в списке, то его &amp;lt;tex&amp;gt;next&amp;lt;/tex&amp;gt; указывает на &amp;lt;tex&amp;gt;null&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сама очередь состоит из двух указателей: на голову &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и на хвост &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, которые можно менять атомарно. Удаление из очереди происходит со стороны головы, добавление - со стороны хвоста.&lt;br /&gt;
&lt;br /&gt;
Узел списка, на который указывает &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, является фиктивным (''dummy''). Данные, хранимые в этом узле, не имеют значения. Изначально очередь состоит из одного ''dummy''-элемента, на который указывают &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 '''class''' Queue&lt;br /&gt;
     dummy = '''new''' Node(null, '''new''' AtomicReference&amp;lt;Node&amp;gt;(null))&lt;br /&gt;
     head = '''new''' AtomicReference&amp;lt;Node&amp;gt;(dummy)&lt;br /&gt;
     tail = '''new''' AtomicReference&amp;lt;Node&amp;gt;(dummy)&lt;br /&gt;
&lt;br /&gt;
// TODO; картинка&lt;br /&gt;
&lt;br /&gt;
Будем поддерживать следующий инвариант: в нашей очереди &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; указывает на узел, находящийся не правее узла, на который указывает &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Идея реализации==&lt;br /&gt;
&lt;br /&gt;
=== Удаление элемента ===&lt;br /&gt;
&lt;br /&gt;
Для удаления элемента необходимо переместить указатель &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; на следующую в списке вершину.&lt;br /&gt;
&lt;br /&gt;
 '''def''' pop(): '''Int'''&lt;br /&gt;
     if (H.next == null):&lt;br /&gt;
         '''throw''' '''new''' EmptyException()&lt;br /&gt;
     H = H.next&lt;br /&gt;
     '''return''' H.data &amp;lt;font color=green&amp;gt;//H - новый фиктивный элемент&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Добавление элемента ===&lt;br /&gt;
&lt;br /&gt;
Создадим новый узел списка, и добавим его в конец очереди. &lt;br /&gt;
&lt;br /&gt;
 '''def''' push(x: '''Int'''):&lt;br /&gt;
     newTail = '''new''' Node(x, new AtomicReference&amp;lt;Node&amp;gt;(null))&lt;br /&gt;
     T.next = newTail &amp;lt;font color=green&amp;gt;//Добавление новой вершины в очередь&amp;lt;/font&amp;gt;&lt;br /&gt;
     T = T.next &amp;lt;font color=green&amp;gt;//Изменение хвоста списка&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Многопоточная реализация ==&lt;br /&gt;
&lt;br /&gt;
Будем при всех изменениях указателей на вершины списка использовать &amp;lt;tex&amp;gt;CAS&amp;lt;/tex&amp;gt; (то есть при изменении  &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;T.next&amp;lt;/tex&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
=== Удаление элемента ===&lt;br /&gt;
&lt;br /&gt;
Для удаления элемента необходимо переместить указатель &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; на следующую в списке вершину.&lt;br /&gt;
&lt;br /&gt;
 '''def''' pop(): '''Int'''&lt;br /&gt;
     '''while''' ('''true'''): &amp;lt;font color=green&amp;gt;//Поток пытается в CAS - цикле поменять указатель на H, пока не получится&amp;lt;/font&amp;gt;&lt;br /&gt;
         head = H.get()&lt;br /&gt;
         if (head.next == null):&lt;br /&gt;
             '''throw''' '''new''' EmptyException()&lt;br /&gt;
         newHead = head.next.get()&lt;br /&gt;
         if ('''CAS'''(H, head, nextHead)):&lt;br /&gt;
             '''return''' newHead.data&lt;br /&gt;
&lt;br /&gt;
=== Добавление элемента ===&lt;br /&gt;
&lt;br /&gt;
Создадим новый узел списка, и добавим его в конец очереди. &lt;br /&gt;
&lt;br /&gt;
 '''def''' push(x: '''Int'''):&lt;br /&gt;
     newTail = '''new''' Node(x, '''new''' AtomicReference&amp;lt;Node&amp;gt;(null))&lt;br /&gt;
     '''while''' ('''true'''): &amp;lt;font color=green&amp;gt;//Поток пытается в CAS - цикле поменять T.next, пока не получится&amp;lt;/font&amp;gt;&lt;br /&gt;
         tail = T.get()&lt;br /&gt;
         curTail = tail.next&lt;br /&gt;
         if ('''CAS'''(curTail, null, newTail)): &amp;lt;font color=green&amp;gt;//Поток пытается добавить элемент в конец очереди&amp;lt;/font&amp;gt;&lt;br /&gt;
             '''break'''&lt;br /&gt;
    '''while''' ('''true'''): &amp;lt;font color=green&amp;gt;//Поток пытается в CAS - цикле поменять указатель на T, пока не получится&amp;lt;/font&amp;gt;&lt;br /&gt;
         tail = T.get()&lt;br /&gt;
         nextTail = tail.next.get()&lt;br /&gt;
         if ('''CAS'''(T, tail, nextTail)):&lt;br /&gt;
             '''break'''&lt;br /&gt;
&lt;br /&gt;
При данной реализации мы сталкиваемся со следующей проблемой&lt;br /&gt;
&lt;br /&gt;
== Описание проблемы ==&lt;br /&gt;
&lt;br /&gt;
Рассмотрим ситуацию, при которой два потока &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; добавляют в очередь элементы &amp;lt;tex&amp;gt;elem&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;elem'&amp;lt;/tex&amp;gt;. Рассмотрим следующую последовательность действий:&lt;br /&gt;
&lt;br /&gt;
# Поток &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; добавляет в очередь новую вершину, изменяя &amp;lt;tex&amp;gt;T.next&amp;lt;/tex&amp;gt;, но не успевает изменить &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; так, чтобы он указывал на только что добавленную вершину.&lt;br /&gt;
# Планировщик операционной системы усыпляет поток &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Поток &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; собирается добавить новую вершину в очередь, но не может этого сделать, так как постоянно проваливает операцию &amp;lt;tex&amp;gt;CAS(T.next, null, newTail)&amp;lt;/tex&amp;gt; (T.next не указывает на &amp;lt;tex&amp;gt;null&amp;lt;/tex&amp;gt;, так как поток &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; на шаге &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; добавил в очередь новую вершину, но не передвинул &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;)&lt;br /&gt;
# Поток &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; не сможет добавить в очередь новую вершину (а следовательно, завершить операцию &amp;lt;tex&amp;gt;push&amp;lt;/tex&amp;gt;), до тех пор, пока планировщик операционной системы не разбудит поток &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;, и поток &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; не завершит добавление (то есть не передвинет &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; на вершину, добавленную на шаге &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;.)&lt;br /&gt;
&lt;br /&gt;
Следовательно, у такой очереди нет гарантии прогресса, и этот алгоритм не lock-free.&lt;br /&gt;
&lt;br /&gt;
== Корректная lock-free реализация ==&lt;br /&gt;
&lt;br /&gt;
=== Основная идея ===&lt;br /&gt;
&lt;br /&gt;
==Примечания==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
== Источники информации==&lt;br /&gt;
* Maurice Herliny &amp;amp; Nir Shavit - The Art of Multiprocessor programming, стр 230&lt;br /&gt;
[[Категория: Параллельное программирование]]&lt;/div&gt;</summary>
		<author><name>185.22.181.139</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D1%8C_%D0%9C%D0%B0%D0%B9%D0%BA%D0%BB%D0%B0_%D0%B8_%D0%A1%D0%BA%D0%BE%D1%82%D1%82%D0%B0&amp;diff=66358</id>
		<title>Очередь Майкла и Скотта</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D1%8C_%D0%9C%D0%B0%D0%B9%D0%BA%D0%BB%D0%B0_%D0%B8_%D0%A1%D0%BA%D0%BE%D1%82%D1%82%D0%B0&amp;diff=66358"/>
				<updated>2018-10-01T16:21:09Z</updated>
		
		<summary type="html">&lt;p&gt;185.22.181.139: /* Корректная lock-free реализация */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В разработке}}&lt;br /&gt;
'''Очередь Майкла и Скотта''' ''(Michael-Scott Queue)'' - алгоритм построения lock-free очереди. Впервые был предложен Maged M. Michael и  Michael L. Scot в статье &amp;lt;ref&amp;gt;[http://www.cs.rochester.edu/~scott/papers/1996_PODC_queues.pdf? Simple, Fast, and Practical Non-Blocking and BlockingConcurrent Queue Algorithms]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
== Структура очереди ==&lt;br /&gt;
&lt;br /&gt;
Очередь моделируется с помощью односвязного списка. Каждый элемент списка (&amp;lt;tex&amp;gt;Node&amp;lt;/tex&amp;gt;) содержит ссылку на хранимые в нём данные и указатель на следующий элемент списка (который можно менять атомарно).&lt;br /&gt;
&lt;br /&gt;
 '''case class''' Node('''val''' data: '''Int''', '''val''' next: AtomicReference&amp;lt;Node&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Если узел &amp;lt;tex&amp;gt;node&amp;lt;/tex&amp;gt; является последним в списке, то его &amp;lt;tex&amp;gt;next&amp;lt;/tex&amp;gt; указывает на &amp;lt;tex&amp;gt;null&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сама очередь состоит из двух указателей: на голову &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и на хвост &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, которые можно менять атомарно. Удаление из очереди происходит со стороны головы, добавление - со стороны хвоста.&lt;br /&gt;
&lt;br /&gt;
Узел списка, на который указывает &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, является фиктивным (''dummy''). Данные, хранимые в этом узле, не имеют значения. Изначально очередь состоит из одного ''dummy''-элемента, на который указывают &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 '''class''' Queue&lt;br /&gt;
     dummy = '''new''' Node(null, '''new''' AtomicReference&amp;lt;Node&amp;gt;(null))&lt;br /&gt;
     head = '''new''' AtomicReference&amp;lt;Node&amp;gt;(dummy)&lt;br /&gt;
     tail = '''new''' AtomicReference&amp;lt;Node&amp;gt;(dummy)&lt;br /&gt;
&lt;br /&gt;
// TODO; картинка&lt;br /&gt;
&lt;br /&gt;
Будем поддерживать следующий инвариант: в нашей очереди &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; указывает на узел, находящийся не правее узла, на который указывает &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Идея реализации==&lt;br /&gt;
&lt;br /&gt;
=== Удаление элемента ===&lt;br /&gt;
&lt;br /&gt;
Для удаления элемента необходимо переместить указатель &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; на следующую в списке вершину.&lt;br /&gt;
&lt;br /&gt;
 '''def''' pop(): '''Int'''&lt;br /&gt;
     if (H.next == null):&lt;br /&gt;
         '''throw''' '''new''' EmptyException()&lt;br /&gt;
     H = H.next&lt;br /&gt;
     '''return''' H.data &amp;lt;font color=green&amp;gt;//H - новый фиктивный элемент&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Добавление элемента ===&lt;br /&gt;
&lt;br /&gt;
Создадим новый узел списка, и добавим его в конец очереди. &lt;br /&gt;
&lt;br /&gt;
 '''def''' push(x: '''Int'''):&lt;br /&gt;
     newTail = '''new''' Node(x, new AtomicReference&amp;lt;Node&amp;gt;(null))&lt;br /&gt;
     T.next = newTail &amp;lt;font color=green&amp;gt;//Добавление новой вершины в очередь&amp;lt;/font&amp;gt;&lt;br /&gt;
     T = T.next &amp;lt;font color=green&amp;gt;//Изменение хвоста списка&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Многопоточная реализация ==&lt;br /&gt;
&lt;br /&gt;
Будем при всех изменениях указателей на вершины списка использовать &amp;lt;tex&amp;gt;CAS&amp;lt;/tex&amp;gt; (то есть при изменении  &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;T.next&amp;lt;/tex&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
=== Удаление элемента ===&lt;br /&gt;
&lt;br /&gt;
Для удаления элемента необходимо переместить указатель &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; на следующую в списке вершину.&lt;br /&gt;
&lt;br /&gt;
 '''def''' pop(): '''Int'''&lt;br /&gt;
     '''while''' ('''true'''): &amp;lt;font color=green&amp;gt;//Поток пытается в CAS - цикле поменять указатель на H, пока не получится&amp;lt;/font&amp;gt;&lt;br /&gt;
         head = H.get()&lt;br /&gt;
         if (head.next == null):&lt;br /&gt;
             '''throw''' '''new''' EmptyException()&lt;br /&gt;
         newHead = head.next.get()&lt;br /&gt;
         if ('''CAS'''(H, head, nextHead)):&lt;br /&gt;
             '''return''' newHead.data&lt;br /&gt;
&lt;br /&gt;
=== Добавление элемента ===&lt;br /&gt;
&lt;br /&gt;
Создадим новый узел списка, и добавим его в конец очереди. &lt;br /&gt;
&lt;br /&gt;
 '''def''' push(x: '''Int'''):&lt;br /&gt;
     newTail = '''new''' Node(x, '''new''' AtomicReference&amp;lt;Node&amp;gt;(null))&lt;br /&gt;
     '''while''' ('''true'''): &amp;lt;font color=green&amp;gt;//Поток пытается в CAS - цикле поменять T.next, пока не получится&amp;lt;/font&amp;gt;&lt;br /&gt;
         tail = T.get()&lt;br /&gt;
         curTail = tail.next&lt;br /&gt;
         if ('''CAS'''(curTail, null, newTail)): &amp;lt;font color=green&amp;gt;//Поток пытается добавить элемент в конец очереди&amp;lt;/font&amp;gt;&lt;br /&gt;
             '''break'''&lt;br /&gt;
    '''while''' ('''true'''): &amp;lt;font color=green&amp;gt;//Поток пытается в CAS - цикле поменять указатель на T, пока не получится&amp;lt;/font&amp;gt;&lt;br /&gt;
         tail = T.get()&lt;br /&gt;
         nextTail = tail.next.get()&lt;br /&gt;
         if ('''CAS'''(T, tail, nextTail)):&lt;br /&gt;
             '''break'''&lt;br /&gt;
&lt;br /&gt;
При данной реализации мы сталкиваемся со следующей проблемой&lt;br /&gt;
&lt;br /&gt;
== Описание проблемы ==&lt;br /&gt;
&lt;br /&gt;
Рассмотрим ситуацию, при которой два потока &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; добавляют в очередь элементы &amp;lt;tex&amp;gt;6&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;7&amp;lt;/tex&amp;gt;. Рассмотрим следующую последовательность действий:&lt;br /&gt;
&lt;br /&gt;
# Поток &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; добавляет в очередь новую вершину, изменяя &amp;lt;tex&amp;gt;T.next&amp;lt;/tex&amp;gt;, но не успевает изменить &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; так, чтобы он указывал на только что добавленную вершину.&lt;br /&gt;
# Планировщик операционной системы усыпляет поток &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Поток &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; собирается добавить новую вершину в очередь, но не может этого сделать, так как постоянно проваливает операцию &amp;lt;tex&amp;gt;CAS(T.next, null, newTail)&amp;lt;/tex&amp;gt; (T.next не указывает на &amp;lt;tex&amp;gt;null&amp;lt;/tex&amp;gt;, так как поток &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; на шаге &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; добавил в очередь новую вершину, но не передвинул &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;)&lt;br /&gt;
# Поток &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; не сможет добавить в очередь новую вершину (а следовательно, завершить операцию &amp;lt;tex&amp;gt;push&amp;lt;/tex&amp;gt;), до тех пор, пока планировщик операционной системы не разбудит поток &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;, и поток &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; не завершит добавление (то есть не передвинет &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; на вершину, добавленную на шаге &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;.)&lt;br /&gt;
&lt;br /&gt;
Следовательно, у такой очереди нет гарантии прогресса, и этот алгоритм не lock-free.&lt;br /&gt;
&lt;br /&gt;
== Корректная lock-free реализация ==&lt;br /&gt;
&lt;br /&gt;
=== Основная идея ===&lt;br /&gt;
&lt;br /&gt;
==Примечания==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
== Источники информации==&lt;br /&gt;
* Maurice Herliny &amp;amp; Nir Shavit - The Art of Multiprocessor programming, стр 230&lt;br /&gt;
[[Категория: Параллельное программирование]]&lt;/div&gt;</summary>
		<author><name>185.22.181.139</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D1%8C_%D0%9C%D0%B0%D0%B9%D0%BA%D0%BB%D0%B0_%D0%B8_%D0%A1%D0%BA%D0%BE%D1%82%D1%82%D0%B0&amp;diff=66357</id>
		<title>Очередь Майкла и Скотта</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D1%8C_%D0%9C%D0%B0%D0%B9%D0%BA%D0%BB%D0%B0_%D0%B8_%D0%A1%D0%BA%D0%BE%D1%82%D1%82%D0%B0&amp;diff=66357"/>
				<updated>2018-10-01T16:16:34Z</updated>
		
		<summary type="html">&lt;p&gt;185.22.181.139: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В разработке}}&lt;br /&gt;
'''Очередь Майкла и Скотта''' ''(Michael-Scott Queue)'' - алгоритм построения lock-free очереди. Впервые был предложен Maged M. Michael и  Michael L. Scot в статье &amp;lt;ref&amp;gt;[http://www.cs.rochester.edu/~scott/papers/1996_PODC_queues.pdf? Simple, Fast, and Practical Non-Blocking and BlockingConcurrent Queue Algorithms]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
== Структура очереди ==&lt;br /&gt;
&lt;br /&gt;
Очередь моделируется с помощью односвязного списка. Каждый элемент списка (&amp;lt;tex&amp;gt;Node&amp;lt;/tex&amp;gt;) содержит ссылку на хранимые в нём данные и указатель на следующий элемент списка (который можно менять атомарно).&lt;br /&gt;
&lt;br /&gt;
 '''case class''' Node('''val''' data: '''Int''', '''val''' next: AtomicReference&amp;lt;Node&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Если узел &amp;lt;tex&amp;gt;node&amp;lt;/tex&amp;gt; является последним в списке, то его &amp;lt;tex&amp;gt;next&amp;lt;/tex&amp;gt; указывает на &amp;lt;tex&amp;gt;null&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сама очередь состоит из двух указателей: на голову &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и на хвост &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, которые можно менять атомарно. Удаление из очереди происходит со стороны головы, добавление - со стороны хвоста.&lt;br /&gt;
&lt;br /&gt;
Узел списка, на который указывает &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, является фиктивным (''dummy''). Данные, хранимые в этом узле, не имеют значения. Изначально очередь состоит из одного ''dummy''-элемента, на который указывают &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 '''class''' Queue&lt;br /&gt;
     dummy = '''new''' Node(null, '''new''' AtomicReference&amp;lt;Node&amp;gt;(null))&lt;br /&gt;
     head = '''new''' AtomicReference&amp;lt;Node&amp;gt;(dummy)&lt;br /&gt;
     tail = '''new''' AtomicReference&amp;lt;Node&amp;gt;(dummy)&lt;br /&gt;
&lt;br /&gt;
// TODO; картинка&lt;br /&gt;
&lt;br /&gt;
Будем поддерживать следующий инвариант: в нашей очереди &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; указывает на узел, находящийся не правее узла, на который указывает &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Идея реализации==&lt;br /&gt;
&lt;br /&gt;
=== Удаление элемента ===&lt;br /&gt;
&lt;br /&gt;
Для удаления элемента необходимо переместить указатель &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; на следующую в списке вершину.&lt;br /&gt;
&lt;br /&gt;
 '''def''' pop(): '''Int'''&lt;br /&gt;
     if (H.next == null):&lt;br /&gt;
         '''throw''' '''new''' EmptyException()&lt;br /&gt;
     H = H.next&lt;br /&gt;
     '''return''' H.data &amp;lt;font color=green&amp;gt;//H - новый фиктивный элемент&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Добавление элемента ===&lt;br /&gt;
&lt;br /&gt;
Создадим новый узел списка, и добавим его в конец очереди. &lt;br /&gt;
&lt;br /&gt;
 '''def''' push(x: '''Int'''):&lt;br /&gt;
     newTail = '''new''' Node(x, new AtomicReference&amp;lt;Node&amp;gt;(null))&lt;br /&gt;
     T.next = newTail &amp;lt;font color=green&amp;gt;//Добавление новой вершины в очередь&amp;lt;/font&amp;gt;&lt;br /&gt;
     T = T.next &amp;lt;font color=green&amp;gt;//Изменение хвоста списка&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Многопоточная реализация ==&lt;br /&gt;
&lt;br /&gt;
Будем при всех изменениях указателей на вершины списка использовать &amp;lt;tex&amp;gt;CAS&amp;lt;/tex&amp;gt; (то есть при изменении  &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;T.next&amp;lt;/tex&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
=== Удаление элемента ===&lt;br /&gt;
&lt;br /&gt;
Для удаления элемента необходимо переместить указатель &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; на следующую в списке вершину.&lt;br /&gt;
&lt;br /&gt;
 '''def''' pop(): '''Int'''&lt;br /&gt;
     '''while''' ('''true'''): &amp;lt;font color=green&amp;gt;//Поток пытается в CAS - цикле поменять указатель на H, пока не получится&amp;lt;/font&amp;gt;&lt;br /&gt;
         head = H.get()&lt;br /&gt;
         if (head.next == null):&lt;br /&gt;
             '''throw''' '''new''' EmptyException()&lt;br /&gt;
         newHead = head.next.get()&lt;br /&gt;
         if ('''CAS'''(H, head, nextHead)):&lt;br /&gt;
             '''return''' newHead.data&lt;br /&gt;
&lt;br /&gt;
=== Добавление элемента ===&lt;br /&gt;
&lt;br /&gt;
Создадим новый узел списка, и добавим его в конец очереди. &lt;br /&gt;
&lt;br /&gt;
 '''def''' push(x: '''Int'''):&lt;br /&gt;
     newTail = '''new''' Node(x, '''new''' AtomicReference&amp;lt;Node&amp;gt;(null))&lt;br /&gt;
     '''while''' ('''true'''): &amp;lt;font color=green&amp;gt;//Поток пытается в CAS - цикле поменять T.next, пока не получится&amp;lt;/font&amp;gt;&lt;br /&gt;
         tail = T.get()&lt;br /&gt;
         curTail = tail.next&lt;br /&gt;
         if ('''CAS'''(curTail, null, newTail)): &amp;lt;font color=green&amp;gt;//Поток пытается добавить элемент в конец очереди&amp;lt;/font&amp;gt;&lt;br /&gt;
             '''break'''&lt;br /&gt;
    '''while''' ('''true'''): &amp;lt;font color=green&amp;gt;//Поток пытается в CAS - цикле поменять указатель на T, пока не получится&amp;lt;/font&amp;gt;&lt;br /&gt;
         tail = T.get()&lt;br /&gt;
         nextTail = tail.next.get()&lt;br /&gt;
         if ('''CAS'''(T, tail, nextTail)):&lt;br /&gt;
             '''break'''&lt;br /&gt;
&lt;br /&gt;
При данной реализации мы сталкиваемся со следующей проблемой&lt;br /&gt;
&lt;br /&gt;
== Описание проблемы ==&lt;br /&gt;
&lt;br /&gt;
Рассмотрим ситуацию, при которой два потока &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; добавляют в очередь элементы &amp;lt;tex&amp;gt;6&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;7&amp;lt;/tex&amp;gt;. Рассмотрим следующую последовательность действий:&lt;br /&gt;
&lt;br /&gt;
# Поток &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; добавляет в очередь новую вершину, изменяя &amp;lt;tex&amp;gt;T.next&amp;lt;/tex&amp;gt;, но не успевает изменить &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; так, чтобы он указывал на только что добавленную вершину.&lt;br /&gt;
# Планировщик операционной системы усыпляет поток &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Поток &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; собирается добавить новую вершину в очередь, но не может этого сделать, так как постоянно проваливает операцию &amp;lt;tex&amp;gt;CAS(T.next, null, newTail)&amp;lt;/tex&amp;gt; (T.next не указывает на &amp;lt;tex&amp;gt;null&amp;lt;/tex&amp;gt;, так как поток &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; на шаге &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; добавил в очередь новую вершину, но не передвинул &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;)&lt;br /&gt;
# Поток &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; не сможет добавить в очередь новую вершину (а следовательно, завершить операцию &amp;lt;tex&amp;gt;push&amp;lt;/tex&amp;gt;), до тех пор, пока планировщик операционной системы не разбудит поток &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;, и поток &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; не завершит добавление (то есть не передвинет &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; на вершину, добавленную на шаге &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;.)&lt;br /&gt;
&lt;br /&gt;
Следовательно, у такой очереди нет гарантии прогресса, и этот алгоритм не lock-free.&lt;br /&gt;
&lt;br /&gt;
== Корректная lock-free реализация ==&lt;br /&gt;
&lt;br /&gt;
==Примечания==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
== Источники информации==&lt;br /&gt;
* Maurice Herliny &amp;amp; Nir Shavit - The Art of Multiprocessor programming, стр 230&lt;br /&gt;
[[Категория: Параллельное программирование]]&lt;/div&gt;</summary>
		<author><name>185.22.181.139</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D1%8C_%D0%9C%D0%B0%D0%B9%D0%BA%D0%BB%D0%B0_%D0%B8_%D0%A1%D0%BA%D0%BE%D1%82%D1%82%D0%B0&amp;diff=66356</id>
		<title>Очередь Майкла и Скотта</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D1%8C_%D0%9C%D0%B0%D0%B9%D0%BA%D0%BB%D0%B0_%D0%B8_%D0%A1%D0%BA%D0%BE%D1%82%D1%82%D0%B0&amp;diff=66356"/>
				<updated>2018-10-01T16:15:46Z</updated>
		
		<summary type="html">&lt;p&gt;185.22.181.139: /* Описание проблемы */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В разработке}}&lt;br /&gt;
'''Очередь Майкла и Скотта''' ''(Michael-Scott Queue)'' - алгоритм построения lock-free очереди. Впервые был предложен Maged M. Michael и  Michael L. Scot в статье &amp;lt;ref&amp;gt;[http://www.cs.rochester.edu/~scott/papers/1996_PODC_queues.pdf? Simple, Fast, and Practical Non-Blocking and BlockingConcurrent Queue Algorithms]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
== Структура очереди ==&lt;br /&gt;
&lt;br /&gt;
Очередь моделируется с помощью односвязного списка. Каждый элемент списка (&amp;lt;tex&amp;gt;Node&amp;lt;/tex&amp;gt;) содержит ссылку на хранимые в нём данные и указатель на следующий элемент списка (который можно менять атомарно).&lt;br /&gt;
&lt;br /&gt;
 '''case class''' Node('''val''' data: '''Int''', '''val''' next: AtomicReference&amp;lt;Node&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Если узел &amp;lt;tex&amp;gt;node&amp;lt;/tex&amp;gt; является последним в списке, то его &amp;lt;tex&amp;gt;next&amp;lt;/tex&amp;gt; указывает на &amp;lt;tex&amp;gt;null&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сама очередь состоит из двух указателей: на голову &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и на хвост &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, которые можно менять атомарно. Удаление из очереди происходит со стороны головы, добавление - со стороны хвоста.&lt;br /&gt;
&lt;br /&gt;
Узел списка, на который указывает &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, является фиктивным (''dummy''). Данные, хранимые в этом узле, не имеют значения. Изначально очередь состоит из одного ''dummy''-элемента, на который указывают &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 '''class''' Queue&lt;br /&gt;
     dummy = '''new''' Node(null, '''new''' AtomicReference&amp;lt;Node&amp;gt;(null))&lt;br /&gt;
     head = '''new''' AtomicReference&amp;lt;Node&amp;gt;(dummy)&lt;br /&gt;
     tail = '''new''' AtomicReference&amp;lt;Node&amp;gt;(dummy)&lt;br /&gt;
&lt;br /&gt;
// TODO; картинка&lt;br /&gt;
&lt;br /&gt;
Будем поддерживать следующий инвариант: в нашей очереди &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; указывает на узел, находящийся не правее узла, на который указывает &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Идея реализации==&lt;br /&gt;
&lt;br /&gt;
=== Удаление элемента ===&lt;br /&gt;
&lt;br /&gt;
Для удаления элемента необходимо переместить указатель &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; на следующую в списке вершину.&lt;br /&gt;
&lt;br /&gt;
 '''def''' pop(): '''Int'''&lt;br /&gt;
     if (H.next == null):&lt;br /&gt;
         '''throw''' '''new''' EmptyException()&lt;br /&gt;
     H = H.next&lt;br /&gt;
     '''return''' H.data &amp;lt;font color=green&amp;gt;//H - новый фиктивный элемент&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Добавление элемента ===&lt;br /&gt;
&lt;br /&gt;
Создадим новый узел списка, и добавим его в конец очереди. &lt;br /&gt;
&lt;br /&gt;
 '''def''' push(x: '''Int'''):&lt;br /&gt;
     newTail = '''new''' Node(x, new AtomicReference&amp;lt;Node&amp;gt;(null))&lt;br /&gt;
     T.next = newTail &amp;lt;font color=green&amp;gt;//Добавление новой вершины в очередь&amp;lt;/font&amp;gt;&lt;br /&gt;
     T = T.next &amp;lt;font color=green&amp;gt;//Изменение хвоста списка&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Многопоточная реализация ==&lt;br /&gt;
&lt;br /&gt;
Будем при всех изменениях указателей на вершины списка использовать &amp;lt;tex&amp;gt;CAS&amp;lt;/tex&amp;gt; (то есть при изменении  &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;T.next&amp;lt;/tex&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
=== Удаление элемента ===&lt;br /&gt;
&lt;br /&gt;
Для удаления элемента необходимо переместить указатель &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; на следующую в списке вершину.&lt;br /&gt;
&lt;br /&gt;
 '''def''' pop(): '''Int'''&lt;br /&gt;
     '''while''' ('''true'''): &amp;lt;font color=green&amp;gt;//Поток пытается в CAS - цикле поменять указатель на H, пока не получится&amp;lt;/font&amp;gt;&lt;br /&gt;
         head = H.get()&lt;br /&gt;
         if (head.next == null):&lt;br /&gt;
             '''throw''' '''new''' EmptyException()&lt;br /&gt;
         newHead = head.next.get()&lt;br /&gt;
         if ('''CAS'''(H, head, nextHead)):&lt;br /&gt;
             '''return''' newHead.data&lt;br /&gt;
&lt;br /&gt;
=== Добавление элемента ===&lt;br /&gt;
&lt;br /&gt;
Создадим новый узел списка, и добавим его в конец очереди. &lt;br /&gt;
&lt;br /&gt;
 '''def''' push(x: '''Int'''):&lt;br /&gt;
     newTail = '''new''' Node(x, '''new''' AtomicReference&amp;lt;Node&amp;gt;(null))&lt;br /&gt;
     '''while''' ('''true'''): &amp;lt;font color=green&amp;gt;//Поток пытается в CAS - цикле поменять T.next, пока не получится&amp;lt;/font&amp;gt;&lt;br /&gt;
         tail = T.get()&lt;br /&gt;
         curTail = tail.next&lt;br /&gt;
         if ('''CAS'''(curTail, null, newTail)): &amp;lt;font color=green&amp;gt;//Поток пытается добавить элемент в конец очереди&amp;lt;/font&amp;gt;&lt;br /&gt;
             '''break'''&lt;br /&gt;
    '''while''' ('''true'''): &amp;lt;font color=green&amp;gt;//Поток пытается в CAS - цикле поменять указатель на T, пока не получится&amp;lt;/font&amp;gt;&lt;br /&gt;
         tail = T.get()&lt;br /&gt;
         nextTail = tail.next.get()&lt;br /&gt;
         if ('''CAS'''(T, tail, nextTail)):&lt;br /&gt;
             '''break'''&lt;br /&gt;
&lt;br /&gt;
При этом мы сталкиваемся со следующей проблемой&lt;br /&gt;
&lt;br /&gt;
==Примечания==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
== Источники информации==&lt;br /&gt;
* Maurice Herliny &amp;amp; Nir Shavit - The Art of Multiprocessor programming, стр 230&lt;br /&gt;
[[Категория: Параллельное программирование]]&lt;/div&gt;</summary>
		<author><name>185.22.181.139</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D1%8C_%D0%9C%D0%B0%D0%B9%D0%BA%D0%BB%D0%B0_%D0%B8_%D0%A1%D0%BA%D0%BE%D1%82%D1%82%D0%B0&amp;diff=66355</id>
		<title>Очередь Майкла и Скотта</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D1%8C_%D0%9C%D0%B0%D0%B9%D0%BA%D0%BB%D0%B0_%D0%B8_%D0%A1%D0%BA%D0%BE%D1%82%D1%82%D0%B0&amp;diff=66355"/>
				<updated>2018-10-01T16:15:04Z</updated>
		
		<summary type="html">&lt;p&gt;185.22.181.139: /* Описание проблемы */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В разработке}}&lt;br /&gt;
'''Очередь Майкла и Скотта''' ''(Michael-Scott Queue)'' - алгоритм построения lock-free очереди. Впервые был предложен Maged M. Michael и  Michael L. Scot в статье &amp;lt;ref&amp;gt;[http://www.cs.rochester.edu/~scott/papers/1996_PODC_queues.pdf? Simple, Fast, and Practical Non-Blocking and BlockingConcurrent Queue Algorithms]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
== Структура очереди ==&lt;br /&gt;
&lt;br /&gt;
Очередь моделируется с помощью односвязного списка. Каждый элемент списка (&amp;lt;tex&amp;gt;Node&amp;lt;/tex&amp;gt;) содержит ссылку на хранимые в нём данные и указатель на следующий элемент списка (который можно менять атомарно).&lt;br /&gt;
&lt;br /&gt;
 '''case class''' Node('''val''' data: '''Int''', '''val''' next: AtomicReference&amp;lt;Node&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Если узел &amp;lt;tex&amp;gt;node&amp;lt;/tex&amp;gt; является последним в списке, то его &amp;lt;tex&amp;gt;next&amp;lt;/tex&amp;gt; указывает на &amp;lt;tex&amp;gt;null&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сама очередь состоит из двух указателей: на голову &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и на хвост &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, которые можно менять атомарно. Удаление из очереди происходит со стороны головы, добавление - со стороны хвоста.&lt;br /&gt;
&lt;br /&gt;
Узел списка, на который указывает &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, является фиктивным (''dummy''). Данные, хранимые в этом узле, не имеют значения. Изначально очередь состоит из одного ''dummy''-элемента, на который указывают &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 '''class''' Queue&lt;br /&gt;
     dummy = '''new''' Node(null, '''new''' AtomicReference&amp;lt;Node&amp;gt;(null))&lt;br /&gt;
     head = '''new''' AtomicReference&amp;lt;Node&amp;gt;(dummy)&lt;br /&gt;
     tail = '''new''' AtomicReference&amp;lt;Node&amp;gt;(dummy)&lt;br /&gt;
&lt;br /&gt;
// TODO; картинка&lt;br /&gt;
&lt;br /&gt;
Будем поддерживать следующий инвариант: в нашей очереди &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; указывает на узел, находящийся не правее узла, на который указывает &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Идея реализации==&lt;br /&gt;
&lt;br /&gt;
=== Удаление элемента ===&lt;br /&gt;
&lt;br /&gt;
Для удаления элемента необходимо переместить указатель &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; на следующую в списке вершину.&lt;br /&gt;
&lt;br /&gt;
 '''def''' pop(): '''Int'''&lt;br /&gt;
     if (H.next == null):&lt;br /&gt;
         '''throw''' '''new''' EmptyException()&lt;br /&gt;
     H = H.next&lt;br /&gt;
     '''return''' H.data &amp;lt;font color=green&amp;gt;//H - новый фиктивный элемент&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Добавление элемента ===&lt;br /&gt;
&lt;br /&gt;
Создадим новый узел списка, и добавим его в конец очереди. &lt;br /&gt;
&lt;br /&gt;
 '''def''' push(x: '''Int'''):&lt;br /&gt;
     newTail = '''new''' Node(x, new AtomicReference&amp;lt;Node&amp;gt;(null))&lt;br /&gt;
     T.next = newTail &amp;lt;font color=green&amp;gt;//Добавление новой вершины в очередь&amp;lt;/font&amp;gt;&lt;br /&gt;
     T = T.next &amp;lt;font color=green&amp;gt;//Изменение хвоста списка&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Многопоточная реализация ==&lt;br /&gt;
&lt;br /&gt;
Будем при всех изменениях указателей на вершины списка использовать &amp;lt;tex&amp;gt;CAS&amp;lt;/tex&amp;gt; (то есть при изменении  &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;T.next&amp;lt;/tex&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
=== Удаление элемента ===&lt;br /&gt;
&lt;br /&gt;
Для удаления элемента необходимо переместить указатель &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; на следующую в списке вершину.&lt;br /&gt;
&lt;br /&gt;
 '''def''' pop(): '''Int'''&lt;br /&gt;
     '''while''' ('''true'''): &amp;lt;font color=green&amp;gt;//Поток пытается в CAS - цикле поменять указатель на H, пока не получится&amp;lt;/font&amp;gt;&lt;br /&gt;
         head = H.get()&lt;br /&gt;
         if (head.next == null):&lt;br /&gt;
             '''throw''' '''new''' EmptyException()&lt;br /&gt;
         newHead = head.next.get()&lt;br /&gt;
         if ('''CAS'''(H, head, nextHead)):&lt;br /&gt;
             '''return''' newHead.data&lt;br /&gt;
&lt;br /&gt;
=== Добавление элемента ===&lt;br /&gt;
&lt;br /&gt;
Создадим новый узел списка, и добавим его в конец очереди. &lt;br /&gt;
&lt;br /&gt;
 '''def''' push(x: '''Int'''):&lt;br /&gt;
     newTail = '''new''' Node(x, '''new''' AtomicReference&amp;lt;Node&amp;gt;(null))&lt;br /&gt;
     '''while''' ('''true'''): &amp;lt;font color=green&amp;gt;//Поток пытается в CAS - цикле поменять T.next, пока не получится&amp;lt;/font&amp;gt;&lt;br /&gt;
         tail = T.get()&lt;br /&gt;
         curTail = tail.next&lt;br /&gt;
         if ('''CAS'''(curTail, null, newTail)): &amp;lt;font color=green&amp;gt;//Поток пытается добавить элемент в конец очереди&amp;lt;/font&amp;gt;&lt;br /&gt;
             '''break'''&lt;br /&gt;
    '''while''' ('''true'''): &amp;lt;font color=green&amp;gt;//Поток пытается в CAS - цикле поменять указатель на T, пока не получится&amp;lt;/font&amp;gt;&lt;br /&gt;
         tail = T.get()&lt;br /&gt;
         nextTail = tail.next.get()&lt;br /&gt;
         if ('''CAS'''(T, tail, nextTail)):&lt;br /&gt;
             '''break'''&lt;br /&gt;
&lt;br /&gt;
При этом мы сталкиваемся со следующей проблемой&lt;br /&gt;
&lt;br /&gt;
=== Описание проблемы ===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим ситуацию, при которой два потока &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; добавляют в очередь элементы &amp;lt;tex&amp;gt;6&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;7&amp;lt;/tex&amp;gt;. Рассмотрим следующую последовательность действий:&lt;br /&gt;
&lt;br /&gt;
# Поток &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; добавляет в очередь новую вершину, изменяя &amp;lt;tex&amp;gt;T.next&amp;lt;/tex&amp;gt;, но не успевает изменить &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; так, чтобы он указывал на только что добавленную вершину.&lt;br /&gt;
# Планировщик операционной системы усыпляет поток &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Поток &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; собирается добавить новую вершину в очередь, но не может этого сделать, так как постоянно проваливает операцию &amp;lt;tex&amp;gt;CAS(T.next, null, newTail)&amp;lt;/tex&amp;gt; (T.next не указывает на &amp;lt;tex&amp;gt;null&amp;lt;/tex&amp;gt;, так как поток &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; на шаге &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; добавил в очередь новую вершину, но не передвинул &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;)&lt;br /&gt;
# Поток &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; не сможет добавить в очередь новую вершину (а следовательно, завершить операцию &amp;lt;tex&amp;gt;push&amp;lt;/tex&amp;gt;), до тех пор, пока планировщик операционной системы не разбудит поток &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;, и поток &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; не завершит добавление (то есть не передвинет &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; на вершину, добавленную на шаге &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;.)&lt;br /&gt;
&lt;br /&gt;
Следовательно, у такой очереди нет гарантии прогресса, и этот алгоритм не lock-free.&lt;br /&gt;
&lt;br /&gt;
==Примечания==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
== Источники информации==&lt;br /&gt;
* Maurice Herliny &amp;amp; Nir Shavit - The Art of Multiprocessor programming, стр 230&lt;br /&gt;
[[Категория: Параллельное программирование]]&lt;/div&gt;</summary>
		<author><name>185.22.181.139</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D1%8C_%D0%9C%D0%B0%D0%B9%D0%BA%D0%BB%D0%B0_%D0%B8_%D0%A1%D0%BA%D0%BE%D1%82%D1%82%D0%B0&amp;diff=66354</id>
		<title>Очередь Майкла и Скотта</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D1%8C_%D0%9C%D0%B0%D0%B9%D0%BA%D0%BB%D0%B0_%D0%B8_%D0%A1%D0%BA%D0%BE%D1%82%D1%82%D0%B0&amp;diff=66354"/>
				<updated>2018-10-01T16:14:03Z</updated>
		
		<summary type="html">&lt;p&gt;185.22.181.139: /* Описание проблемы */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В разработке}}&lt;br /&gt;
'''Очередь Майкла и Скотта''' ''(Michael-Scott Queue)'' - алгоритм построения lock-free очереди. Впервые был предложен Maged M. Michael и  Michael L. Scot в статье &amp;lt;ref&amp;gt;[http://www.cs.rochester.edu/~scott/papers/1996_PODC_queues.pdf? Simple, Fast, and Practical Non-Blocking and BlockingConcurrent Queue Algorithms]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
== Структура очереди ==&lt;br /&gt;
&lt;br /&gt;
Очередь моделируется с помощью односвязного списка. Каждый элемент списка (&amp;lt;tex&amp;gt;Node&amp;lt;/tex&amp;gt;) содержит ссылку на хранимые в нём данные и указатель на следующий элемент списка (который можно менять атомарно).&lt;br /&gt;
&lt;br /&gt;
 '''case class''' Node('''val''' data: '''Int''', '''val''' next: AtomicReference&amp;lt;Node&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Если узел &amp;lt;tex&amp;gt;node&amp;lt;/tex&amp;gt; является последним в списке, то его &amp;lt;tex&amp;gt;next&amp;lt;/tex&amp;gt; указывает на &amp;lt;tex&amp;gt;null&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сама очередь состоит из двух указателей: на голову &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и на хвост &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, которые можно менять атомарно. Удаление из очереди происходит со стороны головы, добавление - со стороны хвоста.&lt;br /&gt;
&lt;br /&gt;
Узел списка, на который указывает &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, является фиктивным (''dummy''). Данные, хранимые в этом узле, не имеют значения. Изначально очередь состоит из одного ''dummy''-элемента, на который указывают &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 '''class''' Queue&lt;br /&gt;
     dummy = '''new''' Node(null, '''new''' AtomicReference&amp;lt;Node&amp;gt;(null))&lt;br /&gt;
     head = '''new''' AtomicReference&amp;lt;Node&amp;gt;(dummy)&lt;br /&gt;
     tail = '''new''' AtomicReference&amp;lt;Node&amp;gt;(dummy)&lt;br /&gt;
&lt;br /&gt;
// TODO; картинка&lt;br /&gt;
&lt;br /&gt;
Будем поддерживать следующий инвариант: в нашей очереди &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; указывает на узел, находящийся не правее узла, на который указывает &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Идея реализации==&lt;br /&gt;
&lt;br /&gt;
=== Удаление элемента ===&lt;br /&gt;
&lt;br /&gt;
Для удаления элемента необходимо переместить указатель &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; на следующую в списке вершину.&lt;br /&gt;
&lt;br /&gt;
 '''def''' pop(): '''Int'''&lt;br /&gt;
     if (H.next == null):&lt;br /&gt;
         '''throw''' '''new''' EmptyException()&lt;br /&gt;
     H = H.next&lt;br /&gt;
     '''return''' H.data &amp;lt;font color=green&amp;gt;//H - новый фиктивный элемент&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Добавление элемента ===&lt;br /&gt;
&lt;br /&gt;
Создадим новый узел списка, и добавим его в конец очереди. &lt;br /&gt;
&lt;br /&gt;
 '''def''' push(x: '''Int'''):&lt;br /&gt;
     newTail = '''new''' Node(x, new AtomicReference&amp;lt;Node&amp;gt;(null))&lt;br /&gt;
     T.next = newTail &amp;lt;font color=green&amp;gt;//Добавление новой вершины в очередь&amp;lt;/font&amp;gt;&lt;br /&gt;
     T = T.next &amp;lt;font color=green&amp;gt;//Изменение хвоста списка&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Многопоточная реализация ==&lt;br /&gt;
&lt;br /&gt;
Будем при всех изменениях указателей на вершины списка использовать &amp;lt;tex&amp;gt;CAS&amp;lt;/tex&amp;gt; (то есть при изменении  &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;T.next&amp;lt;/tex&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
=== Удаление элемента ===&lt;br /&gt;
&lt;br /&gt;
Для удаления элемента необходимо переместить указатель &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; на следующую в списке вершину.&lt;br /&gt;
&lt;br /&gt;
 '''def''' pop(): '''Int'''&lt;br /&gt;
     '''while''' ('''true'''): &amp;lt;font color=green&amp;gt;//Поток пытается в CAS - цикле поменять указатель на H, пока не получится&amp;lt;/font&amp;gt;&lt;br /&gt;
         head = H.get()&lt;br /&gt;
         if (head.next == null):&lt;br /&gt;
             '''throw''' '''new''' EmptyException()&lt;br /&gt;
         newHead = head.next.get()&lt;br /&gt;
         if ('''CAS'''(H, head, nextHead)):&lt;br /&gt;
             '''return''' newHead.data&lt;br /&gt;
&lt;br /&gt;
=== Добавление элемента ===&lt;br /&gt;
&lt;br /&gt;
Создадим новый узел списка, и добавим его в конец очереди. &lt;br /&gt;
&lt;br /&gt;
 '''def''' push(x: '''Int'''):&lt;br /&gt;
     newTail = '''new''' Node(x, '''new''' AtomicReference&amp;lt;Node&amp;gt;(null))&lt;br /&gt;
     '''while''' ('''true'''): &amp;lt;font color=green&amp;gt;//Поток пытается в CAS - цикле поменять T.next, пока не получится&amp;lt;/font&amp;gt;&lt;br /&gt;
         tail = T.get()&lt;br /&gt;
         curTail = tail.next&lt;br /&gt;
         if ('''CAS'''(curTail, null, newTail)): &amp;lt;font color=green&amp;gt;//Поток пытается добавить элемент в конец очереди&amp;lt;/font&amp;gt;&lt;br /&gt;
             '''break'''&lt;br /&gt;
    '''while''' ('''true'''): &amp;lt;font color=green&amp;gt;//Поток пытается в CAS - цикле поменять указатель на T, пока не получится&amp;lt;/font&amp;gt;&lt;br /&gt;
         tail = T.get()&lt;br /&gt;
         nextTail = tail.next.get()&lt;br /&gt;
         if ('''CAS'''(T, tail, nextTail)):&lt;br /&gt;
             '''break'''&lt;br /&gt;
&lt;br /&gt;
При этом мы сталкиваемся со следующей проблемой&lt;br /&gt;
&lt;br /&gt;
=== Описание проблемы ===&lt;br /&gt;
&lt;br /&gt;
Рассмотрим ситуацию, при которой два потока &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; добавляют в очередь элементы &amp;lt;tex&amp;gt;6&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;7&amp;lt;/tex&amp;gt;. Рассмотрим следующую последовательность действий:&lt;br /&gt;
&lt;br /&gt;
# Поток &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; добавляет в очередь новую вершину, изменяя &amp;lt;tex&amp;gt;T.next&amp;lt;/tex&amp;gt;, но не успевает изменить &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; так, чтобы он указывал на только что добавленную вершину.&lt;br /&gt;
# Планировщик операционной системы усыпляет поток &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;.&lt;br /&gt;
# Поток &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; собирается добавить новую вершину в очередь, но не может этого сделать, так как постоянно проваливает операцию &amp;lt;tex&amp;gt;CAS(T.next, null, newTail)&amp;lt;/tex&amp;gt; (T.next не указывает на &amp;lt;tex&amp;gt;null&amp;lt;/tex&amp;gt;, так как поток &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; на шаге &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt; добавил в очередь новую вершину, но не передвинул &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;)&lt;br /&gt;
# Поток &amp;lt;tex&amp;gt;B&amp;lt;/tex&amp;gt; не сможет добавить в очередь новую вершину (а следовательно, завершить операцию &amp;lt;tex&amp;gt;push&amp;lt;/tex&amp;gt;), до тех пор, пока планировщик операционной системы не разбудит поток &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;, и поток &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt; не завершит добавление (то есть не передвинет &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; на вершину, добавленную на шаге &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;.)&lt;br /&gt;
&lt;br /&gt;
Следовательно, у такой очереди нет гарантии прогресса, мы не получили lock-free алгоритм.&lt;br /&gt;
&lt;br /&gt;
==Примечания==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
== Источники информации==&lt;br /&gt;
* Maurice Herliny &amp;amp; Nir Shavit - The Art of Multiprocessor programming, стр 230&lt;br /&gt;
[[Категория: Параллельное программирование]]&lt;/div&gt;</summary>
		<author><name>185.22.181.139</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D1%8C_%D0%9C%D0%B0%D0%B9%D0%BA%D0%BB%D0%B0_%D0%B8_%D0%A1%D0%BA%D0%BE%D1%82%D1%82%D0%B0&amp;diff=66350</id>
		<title>Очередь Майкла и Скотта</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D1%8C_%D0%9C%D0%B0%D0%B9%D0%BA%D0%BB%D0%B0_%D0%B8_%D0%A1%D0%BA%D0%BE%D1%82%D1%82%D0%B0&amp;diff=66350"/>
				<updated>2018-10-01T15:04:48Z</updated>
		
		<summary type="html">&lt;p&gt;185.22.181.139: /* Удаление элемента */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В разработке}}&lt;br /&gt;
'''Очередь Майкла и Скотта''' ''(Michael-Scott Queue)'' - алгоритм построения lock-free очереди. Впервые был предложен Maged M. Michael и  Michael L. Scot в статье &amp;lt;ref&amp;gt;[http://www.cs.rochester.edu/~scott/papers/1996_PODC_queues.pdf? Simple, Fast, and Practical Non-Blocking and BlockingConcurrent Queue Algorithms]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
== Структура очереди ==&lt;br /&gt;
&lt;br /&gt;
Очередь моделируется с помощью односвязного списка. Каждый элемент списка (&amp;lt;tex&amp;gt;Node&amp;lt;/tex&amp;gt;) содержит ссылку на хранимые в нём данные и указатель на следующий элемент списка (который можно менять атомарно).&lt;br /&gt;
&lt;br /&gt;
 '''case class''' Node('''val''' data: '''Int''', '''val''' next: AtomicReference&amp;lt;Node&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Если узел &amp;lt;tex&amp;gt;node&amp;lt;/tex&amp;gt; является последним в списке, то его &amp;lt;tex&amp;gt;next&amp;lt;/tex&amp;gt; указывает на &amp;lt;tex&amp;gt;null&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сама очередь состоит из двух указателей: на голову &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и на хвост &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, которые можно менять атомарно. Удаление из очереди происходит со стороны головы, добавление - со стороны хвоста.&lt;br /&gt;
&lt;br /&gt;
Узел списка, на который указывает &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, является фиктивным (''dummy''). Данные, хранимые в этом узле, не имеют значения. Изначально очередь состоит из одного ''dummy''-элемента, на который указывают &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 '''class''' Queue&lt;br /&gt;
     dummy = '''new''' Node(null, '''new''' AtomicReference&amp;lt;Node&amp;gt;(null))&lt;br /&gt;
     head = '''new''' AtomicReference&amp;lt;Node&amp;gt;(dummy)&lt;br /&gt;
     tail = '''new''' AtomicReference&amp;lt;Node&amp;gt;(dummy)&lt;br /&gt;
&lt;br /&gt;
// TODO; картинка&lt;br /&gt;
&lt;br /&gt;
Будем поддерживать следующий инвариант: в нашей очереди &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; указывает на узел, находящийся не правее узла, на который указывает &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Идея реализации==&lt;br /&gt;
&lt;br /&gt;
=== Удаление элемента ===&lt;br /&gt;
&lt;br /&gt;
Для удаления элемента необходимо переместить указатель &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; на следующую в списке вершину.&lt;br /&gt;
&lt;br /&gt;
 '''def''' pop(): '''Int'''&lt;br /&gt;
     if (H.next == null):&lt;br /&gt;
         '''throw''' '''new''' EmptyException()&lt;br /&gt;
     H = H.next&lt;br /&gt;
     '''return''' H.data &amp;lt;font color=green&amp;gt;//H - новый фиктивный элемент&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Добавление элемента ===&lt;br /&gt;
&lt;br /&gt;
Создадим новый узел списка, и добавим его в конец очереди. &lt;br /&gt;
&lt;br /&gt;
 '''def''' push(x: '''Int'''):&lt;br /&gt;
     newTail = '''new''' Node(x, new AtomicReference&amp;lt;Node&amp;gt;(null))&lt;br /&gt;
     T.next = newTail &amp;lt;font color=green&amp;gt;//Добавление новой вершины в очередь&amp;lt;/font&amp;gt;&lt;br /&gt;
     T = T.next &amp;lt;font color=green&amp;gt;//Изменение хвоста списка&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Многопоточная реализация ==&lt;br /&gt;
&lt;br /&gt;
Будем при всех изменениях указателей на вершины списка использовать &amp;lt;tex&amp;gt;CAS&amp;lt;/tex&amp;gt; (то есть при изменении  &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;T.next&amp;lt;/tex&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
=== Удаление элемента ===&lt;br /&gt;
&lt;br /&gt;
Для удаления элемента необходимо переместить указатель &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; на следующую в списке вершину.&lt;br /&gt;
&lt;br /&gt;
 '''def''' pop(): '''Int'''&lt;br /&gt;
     '''while''' ('''true'''): &amp;lt;font color=green&amp;gt;//Поток пытается в CAS - цикле поменять указатель на H, пока не получится&amp;lt;/font&amp;gt;&lt;br /&gt;
         head = H.get()&lt;br /&gt;
         if (head.next == null):&lt;br /&gt;
             '''throw''' '''new''' EmptyException()&lt;br /&gt;
         newHead = head.next.get()&lt;br /&gt;
         if ('''CAS'''(H, head, nextHead)):&lt;br /&gt;
             '''return''' newHead.data&lt;br /&gt;
&lt;br /&gt;
=== Добавление элемента ===&lt;br /&gt;
&lt;br /&gt;
Создадим новый узел списка, и добавим его в конец очереди. &lt;br /&gt;
&lt;br /&gt;
 '''def''' push(x: '''Int'''):&lt;br /&gt;
     newTail = '''new''' Node(x, '''new''' AtomicReference&amp;lt;Node&amp;gt;(null))&lt;br /&gt;
     '''while''' ('''true'''): &amp;lt;font color=green&amp;gt;//Поток пытается в CAS - цикле поменять T.next, пока не получится&amp;lt;/font&amp;gt;&lt;br /&gt;
         tail = T.get()&lt;br /&gt;
         curTail = tail.next&lt;br /&gt;
         if ('''CAS'''(curTail, null, newTail)): &amp;lt;font color=green&amp;gt;//Поток пытается добавить элемент в конец очереди&amp;lt;/font&amp;gt;&lt;br /&gt;
             '''break'''&lt;br /&gt;
    '''while''' ('''true'''): &amp;lt;font color=green&amp;gt;//Поток пытается в CAS - цикле поменять указатель на T, пока не получится&amp;lt;/font&amp;gt;&lt;br /&gt;
         tail = T.get()&lt;br /&gt;
         nextTail = tail.next.get()&lt;br /&gt;
         if ('''CAS'''(T, tail, nextTail)):&lt;br /&gt;
             '''break'''&lt;br /&gt;
&lt;br /&gt;
При этом мы сталкиваемся со следующей проблемой&lt;br /&gt;
&lt;br /&gt;
=== Описание проблемы ===&lt;br /&gt;
&lt;br /&gt;
==Примечания==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
== Источники информации==&lt;br /&gt;
* Maurice Herliny &amp;amp; Nir Shavit - The Art of Multiprocessor programming, стр 230&lt;br /&gt;
[[Категория: Параллельное программирование]]&lt;/div&gt;</summary>
		<author><name>185.22.181.139</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D1%8C_%D0%9C%D0%B0%D0%B9%D0%BA%D0%BB%D0%B0_%D0%B8_%D0%A1%D0%BA%D0%BE%D1%82%D1%82%D0%B0&amp;diff=66349</id>
		<title>Очередь Майкла и Скотта</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D1%8C_%D0%9C%D0%B0%D0%B9%D0%BA%D0%BB%D0%B0_%D0%B8_%D0%A1%D0%BA%D0%BE%D1%82%D1%82%D0%B0&amp;diff=66349"/>
				<updated>2018-10-01T15:04:27Z</updated>
		
		<summary type="html">&lt;p&gt;185.22.181.139: /* Многопоточная реализация */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В разработке}}&lt;br /&gt;
'''Очередь Майкла и Скотта''' ''(Michael-Scott Queue)'' - алгоритм построения lock-free очереди. Впервые был предложен Maged M. Michael и  Michael L. Scot в статье &amp;lt;ref&amp;gt;[http://www.cs.rochester.edu/~scott/papers/1996_PODC_queues.pdf? Simple, Fast, and Practical Non-Blocking and BlockingConcurrent Queue Algorithms]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
== Структура очереди ==&lt;br /&gt;
&lt;br /&gt;
Очередь моделируется с помощью односвязного списка. Каждый элемент списка (&amp;lt;tex&amp;gt;Node&amp;lt;/tex&amp;gt;) содержит ссылку на хранимые в нём данные и указатель на следующий элемент списка (который можно менять атомарно).&lt;br /&gt;
&lt;br /&gt;
 '''case class''' Node('''val''' data: '''Int''', '''val''' next: AtomicReference&amp;lt;Node&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Если узел &amp;lt;tex&amp;gt;node&amp;lt;/tex&amp;gt; является последним в списке, то его &amp;lt;tex&amp;gt;next&amp;lt;/tex&amp;gt; указывает на &amp;lt;tex&amp;gt;null&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сама очередь состоит из двух указателей: на голову &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и на хвост &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, которые можно менять атомарно. Удаление из очереди происходит со стороны головы, добавление - со стороны хвоста.&lt;br /&gt;
&lt;br /&gt;
Узел списка, на который указывает &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, является фиктивным (''dummy''). Данные, хранимые в этом узле, не имеют значения. Изначально очередь состоит из одного ''dummy''-элемента, на который указывают &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 '''class''' Queue&lt;br /&gt;
     dummy = '''new''' Node(null, '''new''' AtomicReference&amp;lt;Node&amp;gt;(null))&lt;br /&gt;
     head = '''new''' AtomicReference&amp;lt;Node&amp;gt;(dummy)&lt;br /&gt;
     tail = '''new''' AtomicReference&amp;lt;Node&amp;gt;(dummy)&lt;br /&gt;
&lt;br /&gt;
// TODO; картинка&lt;br /&gt;
&lt;br /&gt;
Будем поддерживать следующий инвариант: в нашей очереди &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; указывает на узел, находящийся не правее узла, на который указывает &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Идея реализации==&lt;br /&gt;
&lt;br /&gt;
=== Удаление элемента ===&lt;br /&gt;
&lt;br /&gt;
Для удаления элемента необходимо переместить указатель &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; на следующую в списке вершину.&lt;br /&gt;
&lt;br /&gt;
 '''def''' pop(): '''Int'''&lt;br /&gt;
     if (H.next == null):&lt;br /&gt;
         '''throw''' new EmptyException()&lt;br /&gt;
     H = H.next&lt;br /&gt;
     '''return''' H.data &amp;lt;font color=green&amp;gt;//H - новый фиктивный элемент&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Добавление элемента ===&lt;br /&gt;
&lt;br /&gt;
Создадим новый узел списка, и добавим его в конец очереди. &lt;br /&gt;
&lt;br /&gt;
 '''def''' push(x: '''Int'''):&lt;br /&gt;
     newTail = '''new''' Node(x, new AtomicReference&amp;lt;Node&amp;gt;(null))&lt;br /&gt;
     T.next = newTail &amp;lt;font color=green&amp;gt;//Добавление новой вершины в очередь&amp;lt;/font&amp;gt;&lt;br /&gt;
     T = T.next &amp;lt;font color=green&amp;gt;//Изменение хвоста списка&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Многопоточная реализация ==&lt;br /&gt;
&lt;br /&gt;
Будем при всех изменениях указателей на вершины списка использовать &amp;lt;tex&amp;gt;CAS&amp;lt;/tex&amp;gt; (то есть при изменении  &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;T.next&amp;lt;/tex&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
=== Удаление элемента ===&lt;br /&gt;
&lt;br /&gt;
Для удаления элемента необходимо переместить указатель &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; на следующую в списке вершину.&lt;br /&gt;
&lt;br /&gt;
 '''def''' pop(): '''Int'''&lt;br /&gt;
     '''while''' ('''true'''): &amp;lt;font color=green&amp;gt;//Поток пытается в CAS - цикле поменять указатель на H, пока не получится&amp;lt;/font&amp;gt;&lt;br /&gt;
         head = H.get()&lt;br /&gt;
         if (head.next == null):&lt;br /&gt;
             '''throw''' '''new''' EmptyException()&lt;br /&gt;
         newHead = head.next.get()&lt;br /&gt;
         if ('''CAS'''(H, head, nextHead)):&lt;br /&gt;
             '''return''' newHead.data&lt;br /&gt;
&lt;br /&gt;
=== Добавление элемента ===&lt;br /&gt;
&lt;br /&gt;
Создадим новый узел списка, и добавим его в конец очереди. &lt;br /&gt;
&lt;br /&gt;
 '''def''' push(x: '''Int'''):&lt;br /&gt;
     newTail = '''new''' Node(x, '''new''' AtomicReference&amp;lt;Node&amp;gt;(null))&lt;br /&gt;
     '''while''' ('''true'''): &amp;lt;font color=green&amp;gt;//Поток пытается в CAS - цикле поменять T.next, пока не получится&amp;lt;/font&amp;gt;&lt;br /&gt;
         tail = T.get()&lt;br /&gt;
         curTail = tail.next&lt;br /&gt;
         if ('''CAS'''(curTail, null, newTail)): &amp;lt;font color=green&amp;gt;//Поток пытается добавить элемент в конец очереди&amp;lt;/font&amp;gt;&lt;br /&gt;
             '''break'''&lt;br /&gt;
    '''while''' ('''true'''): &amp;lt;font color=green&amp;gt;//Поток пытается в CAS - цикле поменять указатель на T, пока не получится&amp;lt;/font&amp;gt;&lt;br /&gt;
         tail = T.get()&lt;br /&gt;
         nextTail = tail.next.get()&lt;br /&gt;
         if ('''CAS'''(T, tail, nextTail)):&lt;br /&gt;
             '''break'''&lt;br /&gt;
&lt;br /&gt;
При этом мы сталкиваемся со следующей проблемой&lt;br /&gt;
&lt;br /&gt;
=== Описание проблемы ===&lt;br /&gt;
&lt;br /&gt;
==Примечания==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
== Источники информации==&lt;br /&gt;
* Maurice Herliny &amp;amp; Nir Shavit - The Art of Multiprocessor programming, стр 230&lt;br /&gt;
[[Категория: Параллельное программирование]]&lt;/div&gt;</summary>
		<author><name>185.22.181.139</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D1%8C_%D0%9C%D0%B0%D0%B9%D0%BA%D0%BB%D0%B0_%D0%B8_%D0%A1%D0%BA%D0%BE%D1%82%D1%82%D0%B0&amp;diff=66348</id>
		<title>Очередь Майкла и Скотта</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D1%8C_%D0%9C%D0%B0%D0%B9%D0%BA%D0%BB%D0%B0_%D0%B8_%D0%A1%D0%BA%D0%BE%D1%82%D1%82%D0%B0&amp;diff=66348"/>
				<updated>2018-10-01T15:03:11Z</updated>
		
		<summary type="html">&lt;p&gt;185.22.181.139: /* Добавление элемента */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В разработке}}&lt;br /&gt;
'''Очередь Майкла и Скотта''' ''(Michael-Scott Queue)'' - алгоритм построения lock-free очереди. Впервые был предложен Maged M. Michael и  Michael L. Scot в статье &amp;lt;ref&amp;gt;[http://www.cs.rochester.edu/~scott/papers/1996_PODC_queues.pdf? Simple, Fast, and Practical Non-Blocking and BlockingConcurrent Queue Algorithms]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
== Структура очереди ==&lt;br /&gt;
&lt;br /&gt;
Очередь моделируется с помощью односвязного списка. Каждый элемент списка (&amp;lt;tex&amp;gt;Node&amp;lt;/tex&amp;gt;) содержит ссылку на хранимые в нём данные и указатель на следующий элемент списка (который можно менять атомарно).&lt;br /&gt;
&lt;br /&gt;
 '''case class''' Node('''val''' data: '''Int''', '''val''' next: AtomicReference&amp;lt;Node&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Если узел &amp;lt;tex&amp;gt;node&amp;lt;/tex&amp;gt; является последним в списке, то его &amp;lt;tex&amp;gt;next&amp;lt;/tex&amp;gt; указывает на &amp;lt;tex&amp;gt;null&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сама очередь состоит из двух указателей: на голову &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и на хвост &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, которые можно менять атомарно. Удаление из очереди происходит со стороны головы, добавление - со стороны хвоста.&lt;br /&gt;
&lt;br /&gt;
Узел списка, на который указывает &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, является фиктивным (''dummy''). Данные, хранимые в этом узле, не имеют значения. Изначально очередь состоит из одного ''dummy''-элемента, на который указывают &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 '''class''' Queue&lt;br /&gt;
     dummy = '''new''' Node(null, '''new''' AtomicReference&amp;lt;Node&amp;gt;(null))&lt;br /&gt;
     head = '''new''' AtomicReference&amp;lt;Node&amp;gt;(dummy)&lt;br /&gt;
     tail = '''new''' AtomicReference&amp;lt;Node&amp;gt;(dummy)&lt;br /&gt;
&lt;br /&gt;
// TODO; картинка&lt;br /&gt;
&lt;br /&gt;
Будем поддерживать следующий инвариант: в нашей очереди &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; указывает на узел, находящийся не правее узла, на который указывает &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Идея реализации==&lt;br /&gt;
&lt;br /&gt;
=== Удаление элемента ===&lt;br /&gt;
&lt;br /&gt;
Для удаления элемента необходимо переместить указатель &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; на следующую в списке вершину.&lt;br /&gt;
&lt;br /&gt;
 '''def''' pop(): '''Int'''&lt;br /&gt;
     if (H.next == null):&lt;br /&gt;
         '''throw''' new EmptyException()&lt;br /&gt;
     H = H.next&lt;br /&gt;
     '''return''' H.data &amp;lt;font color=green&amp;gt;//H - новый фиктивный элемент&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Добавление элемента ===&lt;br /&gt;
&lt;br /&gt;
Создадим новый узел списка, и добавим его в конец очереди. &lt;br /&gt;
&lt;br /&gt;
 '''def''' push(x: '''Int'''):&lt;br /&gt;
     newTail = '''new''' Node(x, new AtomicReference&amp;lt;Node&amp;gt;(null))&lt;br /&gt;
     T.next = newTail &amp;lt;font color=green&amp;gt;//Добавление новой вершины в очередь&amp;lt;/font&amp;gt;&lt;br /&gt;
     T = T.next &amp;lt;font color=green&amp;gt;//Изменение хвоста списка&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Многопоточная реализация ==&lt;br /&gt;
&lt;br /&gt;
Будем при всех изменениях указателей на вершины списка использовать &amp;lt;tex&amp;gt;CAS&amp;lt;/tex&amp;gt; (то есть при изменении  &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;T.next&amp;lt;/tex&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
=== Удаление элемента ===&lt;br /&gt;
&lt;br /&gt;
Для удаления элемента необходимо переместить указатель &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; на следующую в списке вершину.&lt;br /&gt;
&lt;br /&gt;
 '''def''' pop(): '''Int'''&lt;br /&gt;
     while (true): &amp;lt;font color=green&amp;gt;//Поток пытается в CAS - цикле поменять указатель на H, пока не получится&amp;lt;/font&amp;gt;&lt;br /&gt;
         head = H.get()&lt;br /&gt;
         if (head.next == null):&lt;br /&gt;
             '''throw''' new EmptyException()&lt;br /&gt;
         newHead = head.next.get()&lt;br /&gt;
         if (CAS(H, head, nextHead)):&lt;br /&gt;
             return newHead.data&lt;br /&gt;
&lt;br /&gt;
=== Добавление элемента ===&lt;br /&gt;
&lt;br /&gt;
Создадим новый узел списка, и добавим его в конец очереди. &lt;br /&gt;
&lt;br /&gt;
 '''def''' push(x: '''Int'''):&lt;br /&gt;
     newTail = '''new''' Node(x, '''new''' AtomicReference&amp;lt;Node&amp;gt;(null))&lt;br /&gt;
     while (true): &amp;lt;font color=green&amp;gt;//Поток пытается в CAS - цикле поменять T.next, пока не получится&amp;lt;/font&amp;gt;&lt;br /&gt;
         tail = T.get()&lt;br /&gt;
         curTail = tail.next&lt;br /&gt;
         if (CAS(curTail, null, newTail)): &amp;lt;font color=green&amp;gt;//Поток пытается добавить элемент в конец очереди&amp;lt;/font&amp;gt;&lt;br /&gt;
             break&lt;br /&gt;
    while (true): &amp;lt;font color=green&amp;gt;//Поток пытается в CAS - цикле поменять указатель на T, пока не получится&amp;lt;/font&amp;gt;&lt;br /&gt;
         tail = T.get()&lt;br /&gt;
         nextTail = tail.next.get()&lt;br /&gt;
         if (CAS(T, tail, nextTail)):&lt;br /&gt;
             break&lt;br /&gt;
&lt;br /&gt;
При этом мы сталкиваемся со следующей проблемой&lt;br /&gt;
&lt;br /&gt;
=== Описание проблемы ===&lt;br /&gt;
&lt;br /&gt;
==Примечания==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
== Источники информации==&lt;br /&gt;
* Maurice Herliny &amp;amp; Nir Shavit - The Art of Multiprocessor programming, стр 230&lt;br /&gt;
[[Категория: Параллельное программирование]]&lt;/div&gt;</summary>
		<author><name>185.22.181.139</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D1%8C_%D0%9C%D0%B0%D0%B9%D0%BA%D0%BB%D0%B0_%D0%B8_%D0%A1%D0%BA%D0%BE%D1%82%D1%82%D0%B0&amp;diff=66347</id>
		<title>Очередь Майкла и Скотта</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D1%8C_%D0%9C%D0%B0%D0%B9%D0%BA%D0%BB%D0%B0_%D0%B8_%D0%A1%D0%BA%D0%BE%D1%82%D1%82%D0%B0&amp;diff=66347"/>
				<updated>2018-10-01T15:02:55Z</updated>
		
		<summary type="html">&lt;p&gt;185.22.181.139: /* Удаление элемента */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В разработке}}&lt;br /&gt;
'''Очередь Майкла и Скотта''' ''(Michael-Scott Queue)'' - алгоритм построения lock-free очереди. Впервые был предложен Maged M. Michael и  Michael L. Scot в статье &amp;lt;ref&amp;gt;[http://www.cs.rochester.edu/~scott/papers/1996_PODC_queues.pdf? Simple, Fast, and Practical Non-Blocking and BlockingConcurrent Queue Algorithms]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
== Структура очереди ==&lt;br /&gt;
&lt;br /&gt;
Очередь моделируется с помощью односвязного списка. Каждый элемент списка (&amp;lt;tex&amp;gt;Node&amp;lt;/tex&amp;gt;) содержит ссылку на хранимые в нём данные и указатель на следующий элемент списка (который можно менять атомарно).&lt;br /&gt;
&lt;br /&gt;
 '''case class''' Node('''val''' data: '''Int''', '''val''' next: AtomicReference&amp;lt;Node&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Если узел &amp;lt;tex&amp;gt;node&amp;lt;/tex&amp;gt; является последним в списке, то его &amp;lt;tex&amp;gt;next&amp;lt;/tex&amp;gt; указывает на &amp;lt;tex&amp;gt;null&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сама очередь состоит из двух указателей: на голову &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и на хвост &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, которые можно менять атомарно. Удаление из очереди происходит со стороны головы, добавление - со стороны хвоста.&lt;br /&gt;
&lt;br /&gt;
Узел списка, на который указывает &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, является фиктивным (''dummy''). Данные, хранимые в этом узле, не имеют значения. Изначально очередь состоит из одного ''dummy''-элемента, на который указывают &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 '''class''' Queue&lt;br /&gt;
     dummy = '''new''' Node(null, '''new''' AtomicReference&amp;lt;Node&amp;gt;(null))&lt;br /&gt;
     head = '''new''' AtomicReference&amp;lt;Node&amp;gt;(dummy)&lt;br /&gt;
     tail = '''new''' AtomicReference&amp;lt;Node&amp;gt;(dummy)&lt;br /&gt;
&lt;br /&gt;
// TODO; картинка&lt;br /&gt;
&lt;br /&gt;
Будем поддерживать следующий инвариант: в нашей очереди &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; указывает на узел, находящийся не правее узла, на который указывает &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Идея реализации==&lt;br /&gt;
&lt;br /&gt;
=== Удаление элемента ===&lt;br /&gt;
&lt;br /&gt;
Для удаления элемента необходимо переместить указатель &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; на следующую в списке вершину.&lt;br /&gt;
&lt;br /&gt;
 '''def''' pop(): '''Int'''&lt;br /&gt;
     if (H.next == null):&lt;br /&gt;
         '''throw''' new EmptyException()&lt;br /&gt;
     H = H.next&lt;br /&gt;
     '''return''' H.data &amp;lt;font color=green&amp;gt;//H - новый фиктивный элемент&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Добавление элемента ===&lt;br /&gt;
&lt;br /&gt;
Создадим новый узел списка, и добавим его в конец очереди. &lt;br /&gt;
&lt;br /&gt;
 '''def''' push(x: '''Int'''):&lt;br /&gt;
     newTail = new Node(x, new AtomicReference&amp;lt;Node&amp;gt;(null))&lt;br /&gt;
     T.next = newTail &amp;lt;font color=green&amp;gt;//Добавление новой вершины в очередь&amp;lt;/font&amp;gt;&lt;br /&gt;
     T = T.next &amp;lt;font color=green&amp;gt;//Изменение хвоста списка&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Многопоточная реализация ==&lt;br /&gt;
&lt;br /&gt;
Будем при всех изменениях указателей на вершины списка использовать &amp;lt;tex&amp;gt;CAS&amp;lt;/tex&amp;gt; (то есть при изменении  &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;T.next&amp;lt;/tex&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
=== Удаление элемента ===&lt;br /&gt;
&lt;br /&gt;
Для удаления элемента необходимо переместить указатель &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; на следующую в списке вершину.&lt;br /&gt;
&lt;br /&gt;
 '''def''' pop(): '''Int'''&lt;br /&gt;
     while (true): &amp;lt;font color=green&amp;gt;//Поток пытается в CAS - цикле поменять указатель на H, пока не получится&amp;lt;/font&amp;gt;&lt;br /&gt;
         head = H.get()&lt;br /&gt;
         if (head.next == null):&lt;br /&gt;
             '''throw''' new EmptyException()&lt;br /&gt;
         newHead = head.next.get()&lt;br /&gt;
         if (CAS(H, head, nextHead)):&lt;br /&gt;
             return newHead.data&lt;br /&gt;
&lt;br /&gt;
=== Добавление элемента ===&lt;br /&gt;
&lt;br /&gt;
Создадим новый узел списка, и добавим его в конец очереди. &lt;br /&gt;
&lt;br /&gt;
 '''def''' push(x: '''Int'''):&lt;br /&gt;
     newTail = '''new''' Node(x, '''new''' AtomicReference&amp;lt;Node&amp;gt;(null))&lt;br /&gt;
     while (true): &amp;lt;font color=green&amp;gt;//Поток пытается в CAS - цикле поменять T.next, пока не получится&amp;lt;/font&amp;gt;&lt;br /&gt;
         tail = T.get()&lt;br /&gt;
         curTail = tail.next&lt;br /&gt;
         if (CAS(curTail, null, newTail)): &amp;lt;font color=green&amp;gt;//Поток пытается добавить элемент в конец очереди&amp;lt;/font&amp;gt;&lt;br /&gt;
             break&lt;br /&gt;
    while (true): &amp;lt;font color=green&amp;gt;//Поток пытается в CAS - цикле поменять указатель на T, пока не получится&amp;lt;/font&amp;gt;&lt;br /&gt;
         tail = T.get()&lt;br /&gt;
         nextTail = tail.next.get()&lt;br /&gt;
         if (CAS(T, tail, nextTail)):&lt;br /&gt;
             break&lt;br /&gt;
&lt;br /&gt;
При этом мы сталкиваемся со следующей проблемой&lt;br /&gt;
&lt;br /&gt;
=== Описание проблемы ===&lt;br /&gt;
&lt;br /&gt;
==Примечания==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
== Источники информации==&lt;br /&gt;
* Maurice Herliny &amp;amp; Nir Shavit - The Art of Multiprocessor programming, стр 230&lt;br /&gt;
[[Категория: Параллельное программирование]]&lt;/div&gt;</summary>
		<author><name>185.22.181.139</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D1%8C_%D0%9C%D0%B0%D0%B9%D0%BA%D0%BB%D0%B0_%D0%B8_%D0%A1%D0%BA%D0%BE%D1%82%D1%82%D0%B0&amp;diff=66346</id>
		<title>Очередь Майкла и Скотта</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D1%8C_%D0%9C%D0%B0%D0%B9%D0%BA%D0%BB%D0%B0_%D0%B8_%D0%A1%D0%BA%D0%BE%D1%82%D1%82%D0%B0&amp;diff=66346"/>
				<updated>2018-10-01T15:02:32Z</updated>
		
		<summary type="html">&lt;p&gt;185.22.181.139: /* Структура очереди */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В разработке}}&lt;br /&gt;
'''Очередь Майкла и Скотта''' ''(Michael-Scott Queue)'' - алгоритм построения lock-free очереди. Впервые был предложен Maged M. Michael и  Michael L. Scot в статье &amp;lt;ref&amp;gt;[http://www.cs.rochester.edu/~scott/papers/1996_PODC_queues.pdf? Simple, Fast, and Practical Non-Blocking and BlockingConcurrent Queue Algorithms]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
== Структура очереди ==&lt;br /&gt;
&lt;br /&gt;
Очередь моделируется с помощью односвязного списка. Каждый элемент списка (&amp;lt;tex&amp;gt;Node&amp;lt;/tex&amp;gt;) содержит ссылку на хранимые в нём данные и указатель на следующий элемент списка (который можно менять атомарно).&lt;br /&gt;
&lt;br /&gt;
 '''case class''' Node('''val''' data: '''Int''', '''val''' next: AtomicReference&amp;lt;Node&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Если узел &amp;lt;tex&amp;gt;node&amp;lt;/tex&amp;gt; является последним в списке, то его &amp;lt;tex&amp;gt;next&amp;lt;/tex&amp;gt; указывает на &amp;lt;tex&amp;gt;null&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сама очередь состоит из двух указателей: на голову &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и на хвост &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, которые можно менять атомарно. Удаление из очереди происходит со стороны головы, добавление - со стороны хвоста.&lt;br /&gt;
&lt;br /&gt;
Узел списка, на который указывает &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, является фиктивным (''dummy''). Данные, хранимые в этом узле, не имеют значения. Изначально очередь состоит из одного ''dummy''-элемента, на который указывают &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 '''class''' Queue&lt;br /&gt;
     dummy = '''new''' Node(null, '''new''' AtomicReference&amp;lt;Node&amp;gt;(null))&lt;br /&gt;
     head = '''new''' AtomicReference&amp;lt;Node&amp;gt;(dummy)&lt;br /&gt;
     tail = '''new''' AtomicReference&amp;lt;Node&amp;gt;(dummy)&lt;br /&gt;
&lt;br /&gt;
// TODO; картинка&lt;br /&gt;
&lt;br /&gt;
Будем поддерживать следующий инвариант: в нашей очереди &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; указывает на узел, находящийся не правее узла, на который указывает &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Идея реализации==&lt;br /&gt;
&lt;br /&gt;
=== Удаление элемента ===&lt;br /&gt;
&lt;br /&gt;
Для удаления элемента необходимо переместить указатель &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; на следующую в списке вершину.&lt;br /&gt;
&lt;br /&gt;
 '''def''' pop(): '''Int'''&lt;br /&gt;
     if (H.next == null):&lt;br /&gt;
         '''throw''' new EmptyException()&lt;br /&gt;
     H = H.next&lt;br /&gt;
     return H.data &amp;lt;font color=green&amp;gt;//H - новый фиктивный элемент&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Добавление элемента ===&lt;br /&gt;
&lt;br /&gt;
Создадим новый узел списка, и добавим его в конец очереди. &lt;br /&gt;
&lt;br /&gt;
 '''def''' push(x: '''Int'''):&lt;br /&gt;
     newTail = new Node(x, new AtomicReference&amp;lt;Node&amp;gt;(null))&lt;br /&gt;
     T.next = newTail &amp;lt;font color=green&amp;gt;//Добавление новой вершины в очередь&amp;lt;/font&amp;gt;&lt;br /&gt;
     T = T.next &amp;lt;font color=green&amp;gt;//Изменение хвоста списка&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Многопоточная реализация ==&lt;br /&gt;
&lt;br /&gt;
Будем при всех изменениях указателей на вершины списка использовать &amp;lt;tex&amp;gt;CAS&amp;lt;/tex&amp;gt; (то есть при изменении  &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;T.next&amp;lt;/tex&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
=== Удаление элемента ===&lt;br /&gt;
&lt;br /&gt;
Для удаления элемента необходимо переместить указатель &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; на следующую в списке вершину.&lt;br /&gt;
&lt;br /&gt;
 '''def''' pop(): '''Int'''&lt;br /&gt;
     while (true): &amp;lt;font color=green&amp;gt;//Поток пытается в CAS - цикле поменять указатель на H, пока не получится&amp;lt;/font&amp;gt;&lt;br /&gt;
         head = H.get()&lt;br /&gt;
         if (head.next == null):&lt;br /&gt;
             '''throw''' new EmptyException()&lt;br /&gt;
         newHead = head.next.get()&lt;br /&gt;
         if (CAS(H, head, nextHead)):&lt;br /&gt;
             return newHead.data&lt;br /&gt;
&lt;br /&gt;
=== Добавление элемента ===&lt;br /&gt;
&lt;br /&gt;
Создадим новый узел списка, и добавим его в конец очереди. &lt;br /&gt;
&lt;br /&gt;
 '''def''' push(x: '''Int'''):&lt;br /&gt;
     newTail = '''new''' Node(x, '''new''' AtomicReference&amp;lt;Node&amp;gt;(null))&lt;br /&gt;
     while (true): &amp;lt;font color=green&amp;gt;//Поток пытается в CAS - цикле поменять T.next, пока не получится&amp;lt;/font&amp;gt;&lt;br /&gt;
         tail = T.get()&lt;br /&gt;
         curTail = tail.next&lt;br /&gt;
         if (CAS(curTail, null, newTail)): &amp;lt;font color=green&amp;gt;//Поток пытается добавить элемент в конец очереди&amp;lt;/font&amp;gt;&lt;br /&gt;
             break&lt;br /&gt;
    while (true): &amp;lt;font color=green&amp;gt;//Поток пытается в CAS - цикле поменять указатель на T, пока не получится&amp;lt;/font&amp;gt;&lt;br /&gt;
         tail = T.get()&lt;br /&gt;
         nextTail = tail.next.get()&lt;br /&gt;
         if (CAS(T, tail, nextTail)):&lt;br /&gt;
             break&lt;br /&gt;
&lt;br /&gt;
При этом мы сталкиваемся со следующей проблемой&lt;br /&gt;
&lt;br /&gt;
=== Описание проблемы ===&lt;br /&gt;
&lt;br /&gt;
==Примечания==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
== Источники информации==&lt;br /&gt;
* Maurice Herliny &amp;amp; Nir Shavit - The Art of Multiprocessor programming, стр 230&lt;br /&gt;
[[Категория: Параллельное программирование]]&lt;/div&gt;</summary>
		<author><name>185.22.181.139</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D1%8C_%D0%9C%D0%B0%D0%B9%D0%BA%D0%BB%D0%B0_%D0%B8_%D0%A1%D0%BA%D0%BE%D1%82%D1%82%D0%B0&amp;diff=66345</id>
		<title>Очередь Майкла и Скотта</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D1%8C_%D0%9C%D0%B0%D0%B9%D0%BA%D0%BB%D0%B0_%D0%B8_%D0%A1%D0%BA%D0%BE%D1%82%D1%82%D0%B0&amp;diff=66345"/>
				<updated>2018-10-01T15:01:15Z</updated>
		
		<summary type="html">&lt;p&gt;185.22.181.139: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В разработке}}&lt;br /&gt;
'''Очередь Майкла и Скотта''' ''(Michael-Scott Queue)'' - алгоритм построения lock-free очереди. Впервые был предложен Maged M. Michael и  Michael L. Scot в статье &amp;lt;ref&amp;gt;[http://www.cs.rochester.edu/~scott/papers/1996_PODC_queues.pdf? Simple, Fast, and Practical Non-Blocking and BlockingConcurrent Queue Algorithms]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
== Структура очереди ==&lt;br /&gt;
&lt;br /&gt;
Очередь моделируется с помощью односвязного списка. Каждый элемент списка (&amp;lt;tex&amp;gt;Node&amp;lt;/tex&amp;gt;) содержит ссылку на хранимые в нём данные и указатель на следующий элемент списка (который можно менять атомарно).&lt;br /&gt;
&lt;br /&gt;
 '''case class''' Node('''val''' data: '''Int''', '''val''' next: AtomicReference&amp;lt;Node&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Если узел &amp;lt;tex&amp;gt;node&amp;lt;/tex&amp;gt; является последним в списке, то его &amp;lt;tex&amp;gt;next&amp;lt;/tex&amp;gt; указывает на &amp;lt;tex&amp;gt;null&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сама очередь состоит из двух указателей: на голову &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и на хвост &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, которые можно менять атомарно. Удаление из очереди происходит со стороны головы, добавление - со стороны хвоста.&lt;br /&gt;
&lt;br /&gt;
Узел списка, на который указывает &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, является фиктивным (''dummy''). Данные, хранимые в этом узле, не имеют значения. Изначально очередь состоит из одного ''dummy''-элемента, на который указывают &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 '''class''' Queue&lt;br /&gt;
     dummy = new Node(null, '''new''' AtomicReference&amp;lt;Node&amp;gt;(null))&lt;br /&gt;
     head = new AtomicReference&amp;lt;Node&amp;gt;(dummy)&lt;br /&gt;
     tail = new AtomicReference&amp;lt;Node&amp;gt;(dummy)&lt;br /&gt;
&lt;br /&gt;
// TODO; картинка&lt;br /&gt;
&lt;br /&gt;
Будем поддерживать следующий инвариант: в нашей очереди &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; указывает на узел, находящийся не правее узла, на который указывает &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Идея реализации==&lt;br /&gt;
&lt;br /&gt;
=== Удаление элемента ===&lt;br /&gt;
&lt;br /&gt;
Для удаления элемента необходимо переместить указатель &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; на следующую в списке вершину.&lt;br /&gt;
&lt;br /&gt;
 '''def''' pop(): '''Int'''&lt;br /&gt;
     if (H.next == null):&lt;br /&gt;
         '''throw''' new EmptyException()&lt;br /&gt;
     H = H.next&lt;br /&gt;
     return H.data &amp;lt;font color=green&amp;gt;//H - новый фиктивный элемент&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Добавление элемента ===&lt;br /&gt;
&lt;br /&gt;
Создадим новый узел списка, и добавим его в конец очереди. &lt;br /&gt;
&lt;br /&gt;
 '''def''' push(x: '''Int'''):&lt;br /&gt;
     newTail = new Node(x, new AtomicReference&amp;lt;Node&amp;gt;(null))&lt;br /&gt;
     T.next = newTail &amp;lt;font color=green&amp;gt;//Добавление новой вершины в очередь&amp;lt;/font&amp;gt;&lt;br /&gt;
     T = T.next &amp;lt;font color=green&amp;gt;//Изменение хвоста списка&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Многопоточная реализация ==&lt;br /&gt;
&lt;br /&gt;
Будем при всех изменениях указателей на вершины списка использовать &amp;lt;tex&amp;gt;CAS&amp;lt;/tex&amp;gt; (то есть при изменении  &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, и &amp;lt;tex&amp;gt;T.next&amp;lt;/tex&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
=== Удаление элемента ===&lt;br /&gt;
&lt;br /&gt;
Для удаления элемента необходимо переместить указатель &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; на следующую в списке вершину.&lt;br /&gt;
&lt;br /&gt;
 '''def''' pop(): '''Int'''&lt;br /&gt;
     while (true): &amp;lt;font color=green&amp;gt;//Поток пытается в CAS - цикле поменять указатель на H, пока не получится&amp;lt;/font&amp;gt;&lt;br /&gt;
         head = H.get()&lt;br /&gt;
         if (head.next == null):&lt;br /&gt;
             '''throw''' new EmptyException()&lt;br /&gt;
         newHead = head.next.get()&lt;br /&gt;
         if (CAS(H, head, nextHead)):&lt;br /&gt;
             return newHead.data&lt;br /&gt;
&lt;br /&gt;
=== Добавление элемента ===&lt;br /&gt;
&lt;br /&gt;
Создадим новый узел списка, и добавим его в конец очереди. &lt;br /&gt;
&lt;br /&gt;
 '''def''' push(x: '''Int'''):&lt;br /&gt;
     newTail = '''new''' Node(x, '''new''' AtomicReference&amp;lt;Node&amp;gt;(null))&lt;br /&gt;
     while (true): &amp;lt;font color=green&amp;gt;//Поток пытается в CAS - цикле поменять T.next, пока не получится&amp;lt;/font&amp;gt;&lt;br /&gt;
         tail = T.get()&lt;br /&gt;
         curTail = tail.next&lt;br /&gt;
         if (CAS(curTail, null, newTail)): &amp;lt;font color=green&amp;gt;//Поток пытается добавить элемент в конец очереди&amp;lt;/font&amp;gt;&lt;br /&gt;
             break&lt;br /&gt;
    while (true): &amp;lt;font color=green&amp;gt;//Поток пытается в CAS - цикле поменять указатель на T, пока не получится&amp;lt;/font&amp;gt;&lt;br /&gt;
         tail = T.get()&lt;br /&gt;
         nextTail = tail.next.get()&lt;br /&gt;
         if (CAS(T, tail, nextTail)):&lt;br /&gt;
             break&lt;br /&gt;
&lt;br /&gt;
При этом мы сталкиваемся со следующей проблемой&lt;br /&gt;
&lt;br /&gt;
=== Описание проблемы ===&lt;br /&gt;
&lt;br /&gt;
==Примечания==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
== Источники информации==&lt;br /&gt;
* Maurice Herliny &amp;amp; Nir Shavit - The Art of Multiprocessor programming, стр 230&lt;br /&gt;
[[Категория: Параллельное программирование]]&lt;/div&gt;</summary>
		<author><name>185.22.181.139</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D1%8C_%D0%9C%D0%B0%D0%B9%D0%BA%D0%BB%D0%B0_%D0%B8_%D0%A1%D0%BA%D0%BE%D1%82%D1%82%D0%B0&amp;diff=66344</id>
		<title>Очередь Майкла и Скотта</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D1%8C_%D0%9C%D0%B0%D0%B9%D0%BA%D0%BB%D0%B0_%D0%B8_%D0%A1%D0%BA%D0%BE%D1%82%D1%82%D0%B0&amp;diff=66344"/>
				<updated>2018-10-01T14:48:12Z</updated>
		
		<summary type="html">&lt;p&gt;185.22.181.139: /* Идея реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В разработке}}&lt;br /&gt;
'''Очередь Майкла и Скотта''' ''(Michael-Scott Queue)'' - алгоритм построения lock-free очереди. Впервые был предложен Maged M. Michael и  Michael L. Scot в статье &amp;lt;ref&amp;gt;[http://www.cs.rochester.edu/~scott/papers/1996_PODC_queues.pdf? Simple, Fast, and Practical Non-Blocking and BlockingConcurrent Queue Algorithms]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
== Структура очереди ==&lt;br /&gt;
&lt;br /&gt;
Очередь моделируется с помощью односвязного списка. Каждый элемент списка (&amp;lt;tex&amp;gt;Node&amp;lt;/tex&amp;gt;) содержит ссылку на хранимые в нём данные и указатель на следующий элемент списка (который можно менять атомарно).&lt;br /&gt;
&lt;br /&gt;
 '''case class''' Node('''val''' data: '''Int''', '''val''' next: AtomicReference&amp;lt;Node&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Если узел &amp;lt;tex&amp;gt;node&amp;lt;/tex&amp;gt; является последним в списке, то его &amp;lt;tex&amp;gt;next&amp;lt;/tex&amp;gt; указывает на &amp;lt;tex&amp;gt;null&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сама очередь состоит из двух указателей: на голову &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и на хвост &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, которые можно менять атомарно. Удаление из очереди происходит со стороны головы, добавление - со стороны хвоста.&lt;br /&gt;
&lt;br /&gt;
Узел списка, на который указывает &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, является фиктивным (''dummy''). Данные, хранимые в этом узле, не имеют значения. Изначально очередь состоит из одного ''dummy''-элемента, на который указывают &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 '''class''' Queue&lt;br /&gt;
     dummy = new Node(null, '''new''' AtomicReference&amp;lt;Node&amp;gt;(null))&lt;br /&gt;
     head = new AtomicReference&amp;lt;Node&amp;gt;(dummy)&lt;br /&gt;
     tail = new AtomicReference&amp;lt;Node&amp;gt;(dummy)&lt;br /&gt;
&lt;br /&gt;
// TODO; картинка&lt;br /&gt;
&lt;br /&gt;
Будем поддерживать следующий инвариант: в нашей очереди &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; указывает на узел, находящийся не правее узла, на который указывает &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Идея реализации==&lt;br /&gt;
&lt;br /&gt;
=== Удаление элемента ===&lt;br /&gt;
&lt;br /&gt;
Для удаления элемента необходимо переместить указатель &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; на следующую в списке вершину.&lt;br /&gt;
&lt;br /&gt;
 '''def''' pop(): '''Int'''&lt;br /&gt;
     if (H.next == null):&lt;br /&gt;
         '''throw''' new EmptyException()&lt;br /&gt;
     H = H.next&lt;br /&gt;
     return H.data &amp;lt;font color=green&amp;gt;//H - новый фиктивный элемент&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Добавление элемента ===&lt;br /&gt;
&lt;br /&gt;
Создадим новый узел списка, и добавим его в конец очереди. &lt;br /&gt;
&lt;br /&gt;
 '''def''' push(x: '''Int'''):&lt;br /&gt;
     newTail = new Node(x, new AtomicReference&amp;lt;Node&amp;gt;(null))&lt;br /&gt;
     T.next = newTail &amp;lt;font color=green&amp;gt;//Добавление новой вершины в очередь&amp;lt;/font&amp;gt;&lt;br /&gt;
     T = T.next &amp;lt;font color=green&amp;gt;//Изменение хвоста списка&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Примечания==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
== Источники информации==&lt;br /&gt;
* Maurice Herliny &amp;amp; Nir Shavit - The Art of Multiprocessor programming, стр 230&lt;br /&gt;
[[Категория: Параллельное программирование]]&lt;/div&gt;</summary>
		<author><name>185.22.181.139</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D1%8C_%D0%9C%D0%B0%D0%B9%D0%BA%D0%BB%D0%B0_%D0%B8_%D0%A1%D0%BA%D0%BE%D1%82%D1%82%D0%B0&amp;diff=66343</id>
		<title>Очередь Майкла и Скотта</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D1%8C_%D0%9C%D0%B0%D0%B9%D0%BA%D0%BB%D0%B0_%D0%B8_%D0%A1%D0%BA%D0%BE%D1%82%D1%82%D0%B0&amp;diff=66343"/>
				<updated>2018-10-01T14:47:38Z</updated>
		
		<summary type="html">&lt;p&gt;185.22.181.139: /* Структура очереди */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В разработке}}&lt;br /&gt;
'''Очередь Майкла и Скотта''' ''(Michael-Scott Queue)'' - алгоритм построения lock-free очереди. Впервые был предложен Maged M. Michael и  Michael L. Scot в статье &amp;lt;ref&amp;gt;[http://www.cs.rochester.edu/~scott/papers/1996_PODC_queues.pdf? Simple, Fast, and Practical Non-Blocking and BlockingConcurrent Queue Algorithms]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
== Структура очереди ==&lt;br /&gt;
&lt;br /&gt;
Очередь моделируется с помощью односвязного списка. Каждый элемент списка (&amp;lt;tex&amp;gt;Node&amp;lt;/tex&amp;gt;) содержит ссылку на хранимые в нём данные и указатель на следующий элемент списка (который можно менять атомарно).&lt;br /&gt;
&lt;br /&gt;
 '''case class''' Node('''val''' data: '''Int''', '''val''' next: AtomicReference&amp;lt;Node&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Если узел &amp;lt;tex&amp;gt;node&amp;lt;/tex&amp;gt; является последним в списке, то его &amp;lt;tex&amp;gt;next&amp;lt;/tex&amp;gt; указывает на &amp;lt;tex&amp;gt;null&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сама очередь состоит из двух указателей: на голову &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и на хвост &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, которые можно менять атомарно. Удаление из очереди происходит со стороны головы, добавление - со стороны хвоста.&lt;br /&gt;
&lt;br /&gt;
Узел списка, на который указывает &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, является фиктивным (''dummy''). Данные, хранимые в этом узле, не имеют значения. Изначально очередь состоит из одного ''dummy''-элемента, на который указывают &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 '''class''' Queue&lt;br /&gt;
     dummy = new Node(null, '''new''' AtomicReference&amp;lt;Node&amp;gt;(null))&lt;br /&gt;
     head = new AtomicReference&amp;lt;Node&amp;gt;(dummy)&lt;br /&gt;
     tail = new AtomicReference&amp;lt;Node&amp;gt;(dummy)&lt;br /&gt;
&lt;br /&gt;
// TODO; картинка&lt;br /&gt;
&lt;br /&gt;
Будем поддерживать следующий инвариант: в нашей очереди &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; указывает на узел, находящийся не правее узла, на который указывает &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Идея реализации==&lt;br /&gt;
&lt;br /&gt;
=== Удаление элемента ===&lt;br /&gt;
&lt;br /&gt;
Для удаления элемента необходимо переместить указатель &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; на следующую в списке вершину.&lt;br /&gt;
&lt;br /&gt;
 '''def''' pop(): '''T'''&lt;br /&gt;
     if (H.next == null):&lt;br /&gt;
         '''throw''' new EmptyException()&lt;br /&gt;
     H = H.next&lt;br /&gt;
     return H.data &amp;lt;font color=green&amp;gt;//H - новый фиктивный элемент&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Добавление элемента ===&lt;br /&gt;
&lt;br /&gt;
Создадим новый узел списка, и добавим его в конец очереди. &lt;br /&gt;
&lt;br /&gt;
 '''def''' push(x: '''T'''):&lt;br /&gt;
     newTail = new Node&amp;lt;'''T'''&amp;gt;(x, new AtomicReference&amp;lt;Node&amp;lt;T&amp;gt;&amp;gt;(null))&lt;br /&gt;
     T.next = newTail &amp;lt;font color=green&amp;gt;//Добавление новой вершины в очередь&amp;lt;/font&amp;gt;&lt;br /&gt;
     T = T.next &amp;lt;font color=green&amp;gt;//Изменение хвоста списка&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Примечания==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
== Источники информации==&lt;br /&gt;
* Maurice Herliny &amp;amp; Nir Shavit - The Art of Multiprocessor programming, стр 230&lt;br /&gt;
[[Категория: Параллельное программирование]]&lt;/div&gt;</summary>
		<author><name>185.22.181.139</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D1%8C_%D0%9C%D0%B0%D0%B9%D0%BA%D0%BB%D0%B0_%D0%B8_%D0%A1%D0%BA%D0%BE%D1%82%D1%82%D0%B0&amp;diff=66342</id>
		<title>Очередь Майкла и Скотта</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D1%8C_%D0%9C%D0%B0%D0%B9%D0%BA%D0%BB%D0%B0_%D0%B8_%D0%A1%D0%BA%D0%BE%D1%82%D1%82%D0%B0&amp;diff=66342"/>
				<updated>2018-10-01T14:46:42Z</updated>
		
		<summary type="html">&lt;p&gt;185.22.181.139: /* Структура очереди */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В разработке}}&lt;br /&gt;
'''Очередь Майкла и Скотта''' ''(Michael-Scott Queue)'' - алгоритм построения lock-free очереди. Впервые был предложен Maged M. Michael и  Michael L. Scot в статье &amp;lt;ref&amp;gt;[http://www.cs.rochester.edu/~scott/papers/1996_PODC_queues.pdf? Simple, Fast, and Practical Non-Blocking and BlockingConcurrent Queue Algorithms]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
== Структура очереди ==&lt;br /&gt;
&lt;br /&gt;
Очередь моделируется с помощью односвязного списка. Каждый элемент списка (&amp;lt;tex&amp;gt;Node&amp;lt;/tex&amp;gt;) содержит ссылку на хранимые в нём данные и указатель на следующий элемент списка (который можно менять атомарно).&lt;br /&gt;
&lt;br /&gt;
 '''case class''' Node('''val''' data: '''Int''', '''val''' next: AtomicReference&amp;lt;Node&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Если узел &amp;lt;tex&amp;gt;node&amp;lt;/tex&amp;gt; является последним в списке, то его &amp;lt;tex&amp;gt;next&amp;lt;/tex&amp;gt; указывает на &amp;lt;tex&amp;gt;null&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сама очередь состоит из двух указателей: на голову &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и на хвост &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, которые можно менять атомарно. Удаление из очереди происходит со стороны головы, добавление - со стороны хвоста.&lt;br /&gt;
&lt;br /&gt;
Узел списка, на который указывает &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, является фиктивным (''dummy''). Данные, хранимые в этом узле, не имеют значения. Изначально очередь состоит из одного ''dummy''-элемента, на который указывают &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 '''class''' Queue&lt;br /&gt;
     dummy = new Node(null, new AtomicReference&amp;lt;Node&amp;gt;(null))&lt;br /&gt;
     head = new AtomicReference&amp;lt;Node&amp;gt;(dummy)&lt;br /&gt;
     tail = new AtomicReference&amp;lt;Node&amp;gt;(dummy)&lt;br /&gt;
&lt;br /&gt;
// TODO; картинка&lt;br /&gt;
&lt;br /&gt;
Будем поддерживать следующий инвариант: в нашей очереди &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; указывает на узел, находящийся не правее узла, на который указывает &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Идея реализации==&lt;br /&gt;
&lt;br /&gt;
=== Удаление элемента ===&lt;br /&gt;
&lt;br /&gt;
Для удаления элемента необходимо переместить указатель &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; на следующую в списке вершину.&lt;br /&gt;
&lt;br /&gt;
 '''def''' pop(): '''T'''&lt;br /&gt;
     if (H.next == null):&lt;br /&gt;
         '''throw''' new EmptyException()&lt;br /&gt;
     H = H.next&lt;br /&gt;
     return H.data &amp;lt;font color=green&amp;gt;//H - новый фиктивный элемент&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Добавление элемента ===&lt;br /&gt;
&lt;br /&gt;
Создадим новый узел списка, и добавим его в конец очереди. &lt;br /&gt;
&lt;br /&gt;
 '''def''' push(x: '''T'''):&lt;br /&gt;
     newTail = new Node&amp;lt;'''T'''&amp;gt;(x, new AtomicReference&amp;lt;Node&amp;lt;T&amp;gt;&amp;gt;(null))&lt;br /&gt;
     T.next = newTail &amp;lt;font color=green&amp;gt;//Добавление новой вершины в очередь&amp;lt;/font&amp;gt;&lt;br /&gt;
     T = T.next &amp;lt;font color=green&amp;gt;//Изменение хвоста списка&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Примечания==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
== Источники информации==&lt;br /&gt;
* Maurice Herliny &amp;amp; Nir Shavit - The Art of Multiprocessor programming, стр 230&lt;br /&gt;
[[Категория: Параллельное программирование]]&lt;/div&gt;</summary>
		<author><name>185.22.181.139</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D1%8C_%D0%9C%D0%B0%D0%B9%D0%BA%D0%BB%D0%B0_%D0%B8_%D0%A1%D0%BA%D0%BE%D1%82%D1%82%D0%B0&amp;diff=66341</id>
		<title>Очередь Майкла и Скотта</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D1%8C_%D0%9C%D0%B0%D0%B9%D0%BA%D0%BB%D0%B0_%D0%B8_%D0%A1%D0%BA%D0%BE%D1%82%D1%82%D0%B0&amp;diff=66341"/>
				<updated>2018-10-01T14:45:37Z</updated>
		
		<summary type="html">&lt;p&gt;185.22.181.139: /* Добавление элемента */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В разработке}}&lt;br /&gt;
'''Очередь Майкла и Скотта''' ''(Michael-Scott Queue)'' - алгоритм построения lock-free очереди. Впервые был предложен Maged M. Michael и  Michael L. Scot в статье &amp;lt;ref&amp;gt;[http://www.cs.rochester.edu/~scott/papers/1996_PODC_queues.pdf? Simple, Fast, and Practical Non-Blocking and BlockingConcurrent Queue Algorithms]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
== Структура очереди ==&lt;br /&gt;
&lt;br /&gt;
Очередь моделируется с помощью односвязного списка. Каждый элемент списка (&amp;lt;tex&amp;gt;Node&amp;lt;/tex&amp;gt;) содержит ссылку на хранимые в нём данные и указатель на следующий элемент списка (который можно менять атомарно).&lt;br /&gt;
&lt;br /&gt;
 '''case class''' Node&amp;lt;'''T'''&amp;gt;('''val''' data: '''T''', '''val''' next: AtomicReference&amp;lt;Node&amp;lt;'''T'''&amp;gt;&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Если узел &amp;lt;tex&amp;gt;node&amp;lt;/tex&amp;gt; является последним в списке, то его &amp;lt;tex&amp;gt;next&amp;lt;/tex&amp;gt; указывает на &amp;lt;tex&amp;gt;null&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сама очередь состоит из двух указателей: на голову &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и на хвост &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, которые можно менять атомарно. Удаление из очереди происходит со стороны головы, добавление - со стороны хвоста.&lt;br /&gt;
&lt;br /&gt;
Узел списка, на который указывает &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, является фиктивным (''dummy''). Данные, хранимые в этом узле, не имеют значения. Изначально очередь состоит из одного ''dummy''-элемента, на который указывают &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 '''class''' Queue&amp;lt;'''T'''&amp;gt;&lt;br /&gt;
     dummy = new Node&amp;lt;'''T'''&amp;gt;(null, new AtomicReference&amp;lt;Node&amp;gt;(null))&lt;br /&gt;
     head = new AtomicReference&amp;lt;Node&amp;lt;'''T'''&amp;gt;&amp;gt;(dummy)&lt;br /&gt;
     tail = new AtomicReference&amp;lt;Node&amp;lt;'''T'''&amp;gt;&amp;gt;(dummy)&lt;br /&gt;
&lt;br /&gt;
// TODO; картинка&lt;br /&gt;
&lt;br /&gt;
Будем поддерживать следующий инвариант: в нашей очереди &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; указывает на узел, находящийся не правее узла, на который указывает &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Идея реализации==&lt;br /&gt;
&lt;br /&gt;
=== Удаление элемента ===&lt;br /&gt;
&lt;br /&gt;
Для удаления элемента необходимо переместить указатель &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; на следующую в списке вершину.&lt;br /&gt;
&lt;br /&gt;
 '''def''' pop(): '''T'''&lt;br /&gt;
     if (H.next == null):&lt;br /&gt;
         '''throw''' new EmptyException()&lt;br /&gt;
     H = H.next&lt;br /&gt;
     return H.data &amp;lt;font color=green&amp;gt;//H - новый фиктивный элемент&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Добавление элемента ===&lt;br /&gt;
&lt;br /&gt;
Создадим новый узел списка, и добавим его в конец очереди. &lt;br /&gt;
&lt;br /&gt;
 '''def''' push(x: '''T'''):&lt;br /&gt;
     newTail = new Node&amp;lt;'''T'''&amp;gt;(x, new AtomicReference&amp;lt;Node&amp;lt;T&amp;gt;&amp;gt;(null))&lt;br /&gt;
     T.next = newTail &amp;lt;font color=green&amp;gt;//Добавление новой вершины в очередь&amp;lt;/font&amp;gt;&lt;br /&gt;
     T = T.next &amp;lt;font color=green&amp;gt;//Изменение хвоста списка&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Примечания==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
== Источники информации==&lt;br /&gt;
* Maurice Herliny &amp;amp; Nir Shavit - The Art of Multiprocessor programming, стр 230&lt;br /&gt;
[[Категория: Параллельное программирование]]&lt;/div&gt;</summary>
		<author><name>185.22.181.139</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D1%8C_%D0%9C%D0%B0%D0%B9%D0%BA%D0%BB%D0%B0_%D0%B8_%D0%A1%D0%BA%D0%BE%D1%82%D1%82%D0%B0&amp;diff=66340</id>
		<title>Очередь Майкла и Скотта</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D1%8C_%D0%9C%D0%B0%D0%B9%D0%BA%D0%BB%D0%B0_%D0%B8_%D0%A1%D0%BA%D0%BE%D1%82%D1%82%D0%B0&amp;diff=66340"/>
				<updated>2018-10-01T14:39:22Z</updated>
		
		<summary type="html">&lt;p&gt;185.22.181.139: /* Удаление элемента */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В разработке}}&lt;br /&gt;
'''Очередь Майкла и Скотта''' ''(Michael-Scott Queue)'' - алгоритм построения lock-free очереди. Впервые был предложен Maged M. Michael и  Michael L. Scot в статье &amp;lt;ref&amp;gt;[http://www.cs.rochester.edu/~scott/papers/1996_PODC_queues.pdf? Simple, Fast, and Practical Non-Blocking and BlockingConcurrent Queue Algorithms]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
== Структура очереди ==&lt;br /&gt;
&lt;br /&gt;
Очередь моделируется с помощью односвязного списка. Каждый элемент списка (&amp;lt;tex&amp;gt;Node&amp;lt;/tex&amp;gt;) содержит ссылку на хранимые в нём данные и указатель на следующий элемент списка (который можно менять атомарно).&lt;br /&gt;
&lt;br /&gt;
 '''case class''' Node&amp;lt;'''T'''&amp;gt;('''val''' data: '''T''', '''val''' next: AtomicReference&amp;lt;Node&amp;lt;'''T'''&amp;gt;&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Если узел &amp;lt;tex&amp;gt;node&amp;lt;/tex&amp;gt; является последним в списке, то его &amp;lt;tex&amp;gt;next&amp;lt;/tex&amp;gt; указывает на &amp;lt;tex&amp;gt;null&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сама очередь состоит из двух указателей: на голову &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и на хвост &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, которые можно менять атомарно. Удаление из очереди происходит со стороны головы, добавление - со стороны хвоста.&lt;br /&gt;
&lt;br /&gt;
Узел списка, на который указывает &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, является фиктивным (''dummy''). Данные, хранимые в этом узле, не имеют значения. Изначально очередь состоит из одного ''dummy''-элемента, на который указывают &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 '''class''' Queue&amp;lt;'''T'''&amp;gt;&lt;br /&gt;
     dummy = new Node&amp;lt;'''T'''&amp;gt;(null, new AtomicReference&amp;lt;Node&amp;gt;(null))&lt;br /&gt;
     head = new AtomicReference&amp;lt;Node&amp;lt;'''T'''&amp;gt;&amp;gt;(dummy)&lt;br /&gt;
     tail = new AtomicReference&amp;lt;Node&amp;lt;'''T'''&amp;gt;&amp;gt;(dummy)&lt;br /&gt;
&lt;br /&gt;
// TODO; картинка&lt;br /&gt;
&lt;br /&gt;
Будем поддерживать следующий инвариант: в нашей очереди &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; указывает на узел, находящийся не правее узла, на который указывает &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Идея реализации==&lt;br /&gt;
&lt;br /&gt;
=== Удаление элемента ===&lt;br /&gt;
&lt;br /&gt;
Для удаления элемента необходимо переместить указатель &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; на следующую в списке вершину.&lt;br /&gt;
&lt;br /&gt;
 '''def''' pop(): '''T'''&lt;br /&gt;
     if (H.next == null):&lt;br /&gt;
         '''throw''' new EmptyException()&lt;br /&gt;
     H = H.next&lt;br /&gt;
     return H.data &amp;lt;font color=green&amp;gt;//H - новый фиктивный элемент&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Добавление элемента ===&lt;br /&gt;
&lt;br /&gt;
==Примечания==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
== Источники информации==&lt;br /&gt;
* Maurice Herliny &amp;amp; Nir Shavit - The Art of Multiprocessor programming, стр 230&lt;br /&gt;
[[Категория: Параллельное программирование]]&lt;/div&gt;</summary>
		<author><name>185.22.181.139</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D1%8C_%D0%9C%D0%B0%D0%B9%D0%BA%D0%BB%D0%B0_%D0%B8_%D0%A1%D0%BA%D0%BE%D1%82%D1%82%D0%B0&amp;diff=66339</id>
		<title>Очередь Майкла и Скотта</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D1%8C_%D0%9C%D0%B0%D0%B9%D0%BA%D0%BB%D0%B0_%D0%B8_%D0%A1%D0%BA%D0%BE%D1%82%D1%82%D0%B0&amp;diff=66339"/>
				<updated>2018-10-01T14:38:58Z</updated>
		
		<summary type="html">&lt;p&gt;185.22.181.139: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В разработке}}&lt;br /&gt;
'''Очередь Майкла и Скотта''' ''(Michael-Scott Queue)'' - алгоритм построения lock-free очереди. Впервые был предложен Maged M. Michael и  Michael L. Scot в статье &amp;lt;ref&amp;gt;[http://www.cs.rochester.edu/~scott/papers/1996_PODC_queues.pdf? Simple, Fast, and Practical Non-Blocking and BlockingConcurrent Queue Algorithms]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
== Структура очереди ==&lt;br /&gt;
&lt;br /&gt;
Очередь моделируется с помощью односвязного списка. Каждый элемент списка (&amp;lt;tex&amp;gt;Node&amp;lt;/tex&amp;gt;) содержит ссылку на хранимые в нём данные и указатель на следующий элемент списка (который можно менять атомарно).&lt;br /&gt;
&lt;br /&gt;
 '''case class''' Node&amp;lt;'''T'''&amp;gt;('''val''' data: '''T''', '''val''' next: AtomicReference&amp;lt;Node&amp;lt;'''T'''&amp;gt;&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Если узел &amp;lt;tex&amp;gt;node&amp;lt;/tex&amp;gt; является последним в списке, то его &amp;lt;tex&amp;gt;next&amp;lt;/tex&amp;gt; указывает на &amp;lt;tex&amp;gt;null&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сама очередь состоит из двух указателей: на голову &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и на хвост &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, которые можно менять атомарно. Удаление из очереди происходит со стороны головы, добавление - со стороны хвоста.&lt;br /&gt;
&lt;br /&gt;
Узел списка, на который указывает &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, является фиктивным (''dummy''). Данные, хранимые в этом узле, не имеют значения. Изначально очередь состоит из одного ''dummy''-элемента, на который указывают &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 '''class''' Queue&amp;lt;'''T'''&amp;gt;&lt;br /&gt;
     dummy = new Node&amp;lt;'''T'''&amp;gt;(null, new AtomicReference&amp;lt;Node&amp;gt;(null))&lt;br /&gt;
     head = new AtomicReference&amp;lt;Node&amp;lt;'''T'''&amp;gt;&amp;gt;(dummy)&lt;br /&gt;
     tail = new AtomicReference&amp;lt;Node&amp;lt;'''T'''&amp;gt;&amp;gt;(dummy)&lt;br /&gt;
&lt;br /&gt;
// TODO; картинка&lt;br /&gt;
&lt;br /&gt;
Будем поддерживать следующий инвариант: в нашей очереди &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; указывает на узел, находящийся не правее узла, на который указывает &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Идея реализации==&lt;br /&gt;
&lt;br /&gt;
=== Удаление элемента ===&lt;br /&gt;
&lt;br /&gt;
Для удаления элемента необходимо переместить указатель &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; на следующую в списке вершину.&lt;br /&gt;
&lt;br /&gt;
 '''def''' pop(): '''T'''&lt;br /&gt;
     if (H.next == null):&lt;br /&gt;
         '''throw''' new EmptyException()&lt;br /&gt;
     H = H.next&lt;br /&gt;
     return H.data &amp;lt;font color=green&amp;gt;H - новый фиктивный элемент&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Добавление элемента ===&lt;br /&gt;
&lt;br /&gt;
==Примечания==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
== Источники информации==&lt;br /&gt;
* Maurice Herliny &amp;amp; Nir Shavit - The Art of Multiprocessor programming, стр 230&lt;br /&gt;
[[Категория: Параллельное программирование]]&lt;/div&gt;</summary>
		<author><name>185.22.181.139</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D1%8C_%D0%9C%D0%B0%D0%B9%D0%BA%D0%BB%D0%B0_%D0%B8_%D0%A1%D0%BA%D0%BE%D1%82%D1%82%D0%B0&amp;diff=66338</id>
		<title>Очередь Майкла и Скотта</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D1%8C_%D0%9C%D0%B0%D0%B9%D0%BA%D0%BB%D0%B0_%D0%B8_%D0%A1%D0%BA%D0%BE%D1%82%D1%82%D0%B0&amp;diff=66338"/>
				<updated>2018-10-01T14:27:23Z</updated>
		
		<summary type="html">&lt;p&gt;185.22.181.139: /* Структура очереди */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В разработке}}&lt;br /&gt;
'''Очередь Майкла и Скотта''' ''(Michael-Scott Queue)'' - алгоритм построения lock-free очереди. Впервые был предложен Maged M. Michael и  Michael L. Scot в статье &amp;lt;ref&amp;gt;[http://www.cs.rochester.edu/~scott/papers/1996_PODC_queues.pdf? Simple, Fast, and Practical Non-Blocking and BlockingConcurrent Queue Algorithms]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
== Структура очереди ==&lt;br /&gt;
&lt;br /&gt;
Очередь моделируется с помощью односвязного списка. Каждый элемент списка (&amp;lt;tex&amp;gt;Node&amp;lt;/tex&amp;gt;) содержит ссылку на хранимые в нём данные и указатель на следующий элемент списка (который можно менять атомарно).&lt;br /&gt;
&lt;br /&gt;
 '''case class''' Node&amp;lt;T&amp;gt;('''val''' data: T, '''val''' next: AtomicReference&amp;lt;Node&amp;lt;T&amp;gt;&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Если узел &amp;lt;tex&amp;gt;node&amp;lt;/tex&amp;gt; является последним в списке, то его &amp;lt;tex&amp;gt;next&amp;lt;/tex&amp;gt; указывает на &amp;lt;tex&amp;gt;null&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Сама очередь состоит из двух указателей: на голову &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и на хвост &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, которые можно менять атомарно. Удаление из очереди происходит со стороны головы, добавление - со стороны хвоста.&lt;br /&gt;
&lt;br /&gt;
Узел списка, на который указывает &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, является фиктивным (''dummy''). Данные, хранимые в этом узле, не имеют значения. Изначально очередь состоит из одного ''dummy''-элемента, на который указывают &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
 '''class''' Queue&amp;lt;T&amp;gt;&lt;br /&gt;
     dummy = new Node(null, new AtomicReference&amp;lt;Node&amp;gt;(null))&lt;br /&gt;
     head = new AtomicReference&amp;lt;Node&amp;gt;(dummy)&lt;br /&gt;
     tail = new AtomicReference&amp;lt;Node&amp;gt;(dummy)&lt;br /&gt;
&lt;br /&gt;
// TODO; картинка&lt;br /&gt;
&lt;br /&gt;
Будем поддерживать следующий инвариант: в нашей очереди &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; указывает на узел, находящийся не правее узла, на который указывает &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Примечания==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
== Источники информации==&lt;br /&gt;
* Maurice Herliny &amp;amp; Nir Shavit - The Art of Multiprocessor programming, стр 230&lt;br /&gt;
[[Категория: Параллельное программирование]]&lt;/div&gt;</summary>
		<author><name>185.22.181.139</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D1%8C_%D0%9C%D0%B0%D0%B9%D0%BA%D0%BB%D0%B0_%D0%B8_%D0%A1%D0%BA%D0%BE%D1%82%D1%82%D0%B0&amp;diff=66337</id>
		<title>Очередь Майкла и Скотта</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D1%8C_%D0%9C%D0%B0%D0%B9%D0%BA%D0%BB%D0%B0_%D0%B8_%D0%A1%D0%BA%D0%BE%D1%82%D1%82%D0%B0&amp;diff=66337"/>
				<updated>2018-10-01T14:24:28Z</updated>
		
		<summary type="html">&lt;p&gt;185.22.181.139: /* Структура очереди */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В разработке}}&lt;br /&gt;
'''Очередь Майкла и Скотта''' ''(Michael-Scott Queue)'' - алгоритм построения lock-free очереди. Впервые был предложен Maged M. Michael и  Michael L. Scot в статье &amp;lt;ref&amp;gt;[http://www.cs.rochester.edu/~scott/papers/1996_PODC_queues.pdf? Simple, Fast, and Practical Non-Blocking and BlockingConcurrent Queue Algorithms]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
== Структура очереди ==&lt;br /&gt;
&lt;br /&gt;
Очередь моделируется с помощью односвязного списка. Каждый элемент списка (&amp;lt;tex&amp;gt;Node&amp;lt;/tex&amp;gt;) содержит ссылку на хранимые в нём данные и указатель на следующий элемент списка (который можно менять атомарно).&lt;br /&gt;
&lt;br /&gt;
 '''case class''' Node&amp;lt;T&amp;gt;('''val''' data: T, '''val''' next: AtomicReference&amp;lt;Node&amp;lt;T&amp;gt;&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Если узел &amp;lt;tex&amp;gt;node&amp;lt;/tex&amp;gt; является последним в списке, то его &amp;lt;tex&amp;gt;net&amp;lt;/tex&amp;gt; указывает на null.&lt;br /&gt;
&lt;br /&gt;
Сама очередь состоит из двух указателей: на голову &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и на хвост &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, которые можно менять атомарно. Удаление из очереди происходит со стороны головы, добавление - со стороны хвоста.&lt;br /&gt;
&lt;br /&gt;
Узел списка, на который указывает &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, является фиктивным (''dummy''). Данные, хранимые в этом узле, не имеют значения. Изначально очередь состоит из одного ''dummy''-элемента, на который указывают &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''class''' Queue&amp;lt;T&amp;gt;:&lt;br /&gt;
    dummy = new Node(null, new AtomicReference&amp;lt;Node&amp;gt;(null))&lt;br /&gt;
    head = new AtomicReference&amp;lt;Node&amp;gt;(dummy)&lt;br /&gt;
    tail = new AtomicReference&amp;lt;Node&amp;gt;(dummy)&lt;br /&gt;
&lt;br /&gt;
==Примечания==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
== Источники информации==&lt;br /&gt;
* Maurice Herliny &amp;amp; Nir Shavit - The Art of Multiprocessor programming, стр 230&lt;br /&gt;
[[Категория: Параллельное программирование]]&lt;/div&gt;</summary>
		<author><name>185.22.181.139</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D1%8C_%D0%9C%D0%B0%D0%B9%D0%BA%D0%BB%D0%B0_%D0%B8_%D0%A1%D0%BA%D0%BE%D1%82%D1%82%D0%B0&amp;diff=66336</id>
		<title>Очередь Майкла и Скотта</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D1%8C_%D0%9C%D0%B0%D0%B9%D0%BA%D0%BB%D0%B0_%D0%B8_%D0%A1%D0%BA%D0%BE%D1%82%D1%82%D0%B0&amp;diff=66336"/>
				<updated>2018-10-01T14:20:29Z</updated>
		
		<summary type="html">&lt;p&gt;185.22.181.139: /* Структура очереди */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В разработке}}&lt;br /&gt;
'''Очередь Майкла и Скотта''' ''(Michael-Scott Queue)'' - алгоритм построения lock-free очереди. Впервые был предложен Maged M. Michael и  Michael L. Scot в статье &amp;lt;ref&amp;gt;[http://www.cs.rochester.edu/~scott/papers/1996_PODC_queues.pdf? Simple, Fast, and Practical Non-Blocking and BlockingConcurrent Queue Algorithms]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
== Структура очереди ==&lt;br /&gt;
&lt;br /&gt;
Очередь моделируется с помощью односвязного списка. Каждый элемент списка (&amp;lt;tex&amp;gt;Node&amp;lt;/tex&amp;gt;) содержит ссылку на хранимые в нём данные и указатель на следующий элемент списка (который можно менять атомарно).&lt;br /&gt;
&lt;br /&gt;
 '''case class''' Node&amp;lt;T&amp;gt;('''val''' data: T, '''val''' next: AtomicReference&amp;lt;Node&amp;lt;T&amp;gt;&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
Сама очередь состоит из двух указателей: на голову &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt; и на хвост &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt;, которые можно менять атомарно. Удаление из очереди происходит со стороны головы, добавление - со стороны хвоста.&lt;br /&gt;
&lt;br /&gt;
Узел списка, на который указывает &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;, является фиктивным (''dummy''). Данные, хранимые в этом узле, не имеют значения. Изначально очередь состоит из одного ''dummy''-элемента, на который указывают &amp;lt;tex&amp;gt;T&amp;lt;/tex&amp;gt; и &amp;lt;tex&amp;gt;H&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Примечания==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
== Источники информации==&lt;br /&gt;
* Maurice Herliny &amp;amp; Nir Shavit - The Art of Multiprocessor programming, стр 230&lt;br /&gt;
[[Категория: Параллельное программирование]]&lt;/div&gt;</summary>
		<author><name>185.22.181.139</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D1%8C_%D0%9C%D0%B0%D0%B9%D0%BA%D0%BB%D0%B0_%D0%B8_%D0%A1%D0%BA%D0%BE%D1%82%D1%82%D0%B0&amp;diff=66335</id>
		<title>Очередь Майкла и Скотта</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D1%8C_%D0%9C%D0%B0%D0%B9%D0%BA%D0%BB%D0%B0_%D0%B8_%D0%A1%D0%BA%D0%BE%D1%82%D1%82%D0%B0&amp;diff=66335"/>
				<updated>2018-10-01T10:52:19Z</updated>
		
		<summary type="html">&lt;p&gt;185.22.181.139: /* Структура очереди */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В разработке}}&lt;br /&gt;
'''Очередь Майкла и Скотта''' ''(Michael-Scott Queue)'' - алгоритм построения lock-free очереди. Впервые был предложен Maged M. Michael и  Michael L. Scot в статье &amp;lt;ref&amp;gt;[http://www.cs.rochester.edu/~scott/papers/1996_PODC_queues.pdf? Simple, Fast, and Practical Non-Blocking and BlockingConcurrent Queue Algorithms]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
== Структура очереди ==&lt;br /&gt;
&lt;br /&gt;
Очередь моделируется с помощью односвязного списка. Каждый элемент списка (&amp;lt;tex&amp;gt;Node&amp;lt;/tex&amp;gt;) содержит ссылку на хранимые в нём данные и указатель на следующий элемент списка (который можно менять атомарно).&lt;br /&gt;
&lt;br /&gt;
 '''case class''' Node&amp;lt;T&amp;gt;('''val''' data: T, '''val''' next: AtomicReference&amp;lt;Node&amp;lt;T&amp;gt;&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
==Примечания==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
== Источники информации==&lt;br /&gt;
* Maurice Herliny &amp;amp; Nir Shavit - The Art of Multiprocessor programming, стр 230&lt;br /&gt;
[[Категория: Параллельное программирование]]&lt;/div&gt;</summary>
		<author><name>185.22.181.139</name></author>	</entry>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D1%8C_%D0%9C%D0%B0%D0%B9%D0%BA%D0%BB%D0%B0_%D0%B8_%D0%A1%D0%BA%D0%BE%D1%82%D1%82%D0%B0&amp;diff=66333</id>
		<title>Очередь Майкла и Скотта</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%9E%D1%87%D0%B5%D1%80%D0%B5%D0%B4%D1%8C_%D0%9C%D0%B0%D0%B9%D0%BA%D0%BB%D0%B0_%D0%B8_%D0%A1%D0%BA%D0%BE%D1%82%D1%82%D0%B0&amp;diff=66333"/>
				<updated>2018-10-01T08:13:44Z</updated>
		
		<summary type="html">&lt;p&gt;185.22.181.139: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{В разработке}}&lt;br /&gt;
'''Очередь Майкла и Скотта''' ''(Michael-Scott Queue)'' - алгоритм построения lock-free очереди. Впервые был предложен Maged M. Michael и  Michael L. Scot в статье &amp;lt;ref&amp;gt;[http://www.cs.rochester.edu/~scott/papers/1996_PODC_queues.pdf? Simple, Fast, and Practical Non-Blocking and BlockingConcurrent Queue Algorithms]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
== Структура очереди ==&lt;br /&gt;
&lt;br /&gt;
Очередь моделируется с помощью односвязного списка. Каждый элемент списка (&amp;lt;tex&amp;gt;Node&amp;lt;/tex&amp;gt;) содержит ссылку на хранимые в нём данные и указатель на следующий элемент списка (который можно менять атомарно).&lt;br /&gt;
&lt;br /&gt;
 '''data class''' Node&amp;lt;T&amp;gt;('''val''' data: T, '''val''' next: AtomicReference&amp;lt;Node&amp;lt;T&amp;gt;?&amp;gt;)&lt;br /&gt;
     &lt;br /&gt;
&lt;br /&gt;
==Примечания==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
== Источники информации==&lt;br /&gt;
* Maurice Herliny &amp;amp; Nir Shavit - The Art of Multiprocessor programming, стр 230&lt;br /&gt;
[[Категория: Параллельное программирование]]&lt;/div&gt;</summary>
		<author><name>185.22.181.139</name></author>	</entry>

	</feed>