2017-10-18 102 views
-1

我測試簡單的代碼C#線程和鎖定

static Thread _readThread = null; 
    static private Object thisLock = new Object(); 
    static int a = 1; 

    private static void ReadComPort() 
    { 
     lock (thisLock) 
     { 
      for (int i = 0; i < 3; i++) 
      { 
       Console.WriteLine(Thread.CurrentThread.Name + " " + a++.ToString()); 
       Thread.Sleep(1000); 
      } 
     } 
    } 

    static void Main(string[] args) 
    { 
     for (int i = 0; i < 3; i++) 
     { 
      _readThread = new Thread(new ThreadStart(ReadComPort)); 
      _readThread.IsBackground = true; 
      _readThread.Name = i.ToString(); 
      _readThread.Start(); 
      //Thread.Sleep(50); 
     } 

     Console.WriteLine("End"); 
     Console.ReadKey(); 
    } 

但爲什麼執行順序和線程的混亂啓動: 0,2,1爲什麼呢?

控制檯輸出:

0 1 
End 
0 2 
0 3 
2 4 
2 5 
2 6 
1 7 
1 8 
1 9 
+2

你*期待*和*爲什麼*?請注意,您的低迭代次數意味着*線程之間的任何交互*不太可能。 –

+0

當一個線程啓動時,不能保證立即運行,也不會按照與其他線程相比被啓動的順序 –

+0

您可以使用Task.ContinueWith',隊列來運行線程,隊列/優先級來同步對控制檯的訪問,還有什麼..應該是更多的,但絕對不會運行一些線程,並期望他們組織自己,因爲你沒有告訴他們... – Sinatr

回答

2

因爲你不能指望線程啓動或在一個特定的順序運行。操作系統按照它想要的方式安排線程。有時它會暫停一個線程,執行另一個線程,然後再回到原始線程。

在這裏您會看到線程幾乎同時啓動。顯然(從輸出)線程0贏得它的第一個鎖。然後,通過純粹的機會,線程2比線程1更早地獲得鎖定。由於線程相互之間不久創建,這可能會完全不同。如所說:沒有保證。

2

鎖定並不能保證順序:在開始Does lock() guarantee acquired in order requested?

而且,在你的代碼,你應該等待你的線程在你的for循環的末端,以沒有「結束」來完成 - 如果你按一個鍵,當線程仍在運行時,您將退出,並且您可能會有意外的行爲。