2017-10-18 103 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循环的末端,以没有“结束”来完成 - 如果你按一个键,当线程仍在运行时,您将退出,并且您可能会有意外的行为。