2015-04-07 66 views
0

嘿,我使用下面的代碼來實現併發堆棧。在下面的代碼中,單獨爲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

當兩個線程正在運行併發時沒有排序。因此,沒有什麼可以保存的。 – Holger

回答

0

從我瞭解互斥鎖和併發鎖是的,它應該保留排序。據我所知,當你鎖定一個互斥體時,另一個線程也不能鎖定該互斥體並繼續。因此,它會停止執行,直到互斥鎖被解鎖並且它可以繼續。 2個線程不能同時訪問堆棧並且第二個線程被迫等待的事實應該保持彈出和推送的順序。

0

如果您希望對接近​​塊的線程執行嚴格的FIFO排序,則不會像使用內部鎖那樣得到它。也就是說,如果有很多線程等待synchronized(_objLock)可用,稍後到達的線程可能會在之前到達的線程之前進入該塊。

這就是所謂的螺紋掛鉤,並允許作爲內在鎖定不公平。如果你想要一個公平鎖定比你需要使用new ReentrantLock(true)真實指示鎖定是公平的。

這裏給出的鎖定是保證同步塊中的任何線程將是唯一正在執行的線程。也就是說,push和pop的順序會保留每個線程,因爲它看到當前狀態下的堆棧。