嘿我使用下面的代码来实现并发堆栈。在下面的代码中,已经单独获取了push和pop的锁定,但这并不会使Push和pop相互干扰。按顺序使堆栈实现正确Pop不能与push一起发生,而是在push之前或之后(我是否正确?)。但是如果两个线程按顺序调用push和pop,那么这个程序会保留顺序吗?
public class ConcurrentStackL
{
object _objLock;
internal class Node
{
internal T _item;
internal Node _next;
public Node(T item, Node next) { _item = item; _next = next; }
}
private Node _head = null;
private bool _isEmpty;
public ConcurrentStackL()
{
_head = new Node(default(T), _head);
_objLock = new object();
_isEmpty = true;
}
public void Push(T item)
{
lock (_objLock)
{
_head = new Node(item, _head);
if (!_isEmpty)
_isEmpty = false;
}
}
public T Pop()
{
T item;
lock (_objLock)
{
if (_head._next == null)
throw new IndexOutOfRangeException("Stack is empty");
item = _head._item;
_head = _head._next;
if (_head._next == null)
_isEmpty = true;
}
return item;
}
}
答案 0 :(得分:0)
从我对互斥锁和并发锁的理解是的,它应该保留顺序。据我所知,当您锁定互斥锁时,另一个线程也无法锁定该互斥锁并继续操作。因此,它会停止执行,直到互斥锁解锁并且可以继续。 2个线程无法同时访问堆栈而第二个线程被迫等待的事实应该保持弹出和推送的顺序。
答案 1 :(得分:0)
如果您希望对接近synchronized
块的线程进行严格的FIFO排序,则不会像在此处那样使用内部锁定。也就是说,如果许多线程等待synchronized(_objLock)
可用,稍后到达的线程可能会在之前到达的线程之前进入该块。
这称为线程限制,并且被允许因为内部锁定不公平。如果你想要一个 fair 锁,你需要使用new ReentrantLock(true)
,其中true表示锁是公平的。
这里给出的锁定是确保同步块中的任何线程都是唯一执行的线程。也就是说,当每个线程看到当前状态的堆栈时,将保留push和pop的顺序。