JD2022-TU1/main/tools/framework/JD.Collections/Lockless/OneProducerOneConsumerLocklessQueue.cs

72 lines
1.7 KiB
C#

namespace JD.Collections.Lockless
{
/// <summary>
/// A simple lockless queue. Will ONLY work with ONE producer thread and ONE consumer thread.
/// </summary>
/// <remarks>
/// Inspired from http://www.ddj.com/architect/210604448?pgno=2 (Dr. Dobb's: Writing Lock-Free Code: A Corrected Queue)
/// </remarks>
public class OneProducerOneConsumerLocklessQueue<T>
{
#region Variables
private Node m_first; // for producer only
private volatile Node m_divider, m_last; // shared
#endregion
#region Constructor
public OneProducerOneConsumerLocklessQueue()
{
// add dummy separator
m_first = m_divider = m_last = new Node(default(T));
}
#endregion
#region Methods
public void Produce(T value)
{
m_last.Next = new Node(value); // add the new item
m_last = m_last.Next; // publish it
while (m_first != m_divider)
{
// trim unused nodes
m_first = m_first.Next;
}
}
public bool Consume(out T value)
{
if (m_divider != m_last)
{
// if queue is nonempty
value = m_divider.Next.Value; // copy it back
m_divider = m_divider.Next; // publish that we took it
return true;
}
value = default(T);
return false;
}
#endregion
#region Inner Types
private class Node
{
public readonly T Value;
public Node Next;
public Node(T value)
{
Value = value;
}
}
#endregion
}
}