2014-02-14 122 views
0

我寫了這個控制檯程序:如何同步多線程

static void Main(string[] args) 
{ 
    object sync = new object(); 
    Thread[] t = new Thread[10]; 
    int count = 0; 

    for (var i = 0; i < t.Length; i++) 
    { 
     t[i] = new Thread(() => 
     { 
      lock (sync) 
      { 
       int inc = count; 
       Console.WriteLine("Count: {0}", count); 
       count = inc + 1; 
      } 
     }); 
    } 

    foreach (var t1 in t) 
    { 
     t1.Start(); 
    } 

    foreach (var t1 in t) 
    { 
     t1.Join(); 
     Console.WriteLine("\nFinal Count= {0}", count); 
     Console.ReadKey(); 
    } 
} 

我得到這樣的結果輸出:

Count: 0 
Count: 1 
Count: 2 
Count: 3 
Count: 4 
Count: 5 
Count: 6 
Count: 7 

Final Count= 7 
Count: 8 
Count: 9 

,當我運行多個應用程序時,我得到更多的不同的結果 ,但我希望看到這樣的結果:

Count: 0 
Count: 1 
Count: 2 
Count: 3 
Count: 4 
Count: 5 
Count: 6 
Count: 7 
Count: 8 
Count: 9 

Final Count= 10 

爲什麼它返回不同的resul我如何解決這個問題?

+0

'數= INC + 1它們同步;'變得毫無意義。張貼實際的代碼。 –

+0

「最終計數」是可以實現的,但如果你想要數字,那麼就不要使用線程。 –

回答

1

好,而不是這樣的:

foreach (var t1 in t) 
{ 
    t1.Join(); 
    Console.WriteLine("\nFinal Count= {0}", count); 
    Console.ReadKey(); 
} 

你應該寫:

foreach (var t1 in t) 
{ 
    t1.Join(); 

} 
Console.WriteLine("\nFinal Count= {0}", count); 
Console.ReadKey(); 

否則,你將有一個賽車和你的代碼將undeterministic。

+0

事實上 - 隨着原始代碼的寫入,只要檢測到任何一個線程完成,就會顯示「最終計數」。實際上,我很驚訝「最終計數」消息只出現一次,因爲我期望每個線程都會看到一次... –

+0

這將是如此,但他在循環內有Console.ReadKey() 。 –

+0

當然 - 該計劃甚至沒有運行完成。 \ * facepalm \ * –

2

儘量不要手動創建/終止這樣的線程,這是一個耗時的操作,它不能很好地擴展。使用ThreadPool代替。

或者更好的使用任務,利用await Task.WhenAll(list of your tasks)

+0

沒那麼快。這顯然是「演示」代碼,它取決於稍後將在實際線程中執行什麼。 –

+0

@HenkHolterman我明白你的意思(它是有效的),但我仍然會推薦任務而不是線程。除非OP提供了有關線程爲什麼比任務更好的信息(長時間運行的操作等),否則任務將提供更簡單的方法來同步執行。 – ken2k