2017-10-18 4 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'を使用してスレッドを実行し、queue/priorityを使用してConsoleへのアクセスを同期させ、 ..より多くのはずですが、確かにいくつかのスレッドを実行しておらず、あなたに指示していないときに自分自身を整理することを期待しています。 – Sinatr

答えて

2

あなたはスレッドが開始または特定の順序で実行するように期待することはできませんので。 OSはスレッドのスケジュールをスケジューリングします。スレッドを保留にし、別のスレッドを実行して元のスレッドに戻すこともあります。

スレッドがほぼ同時に開始することがわかります。明らかに(出力から)スレッド0は最初のロックに勝ちます。次に、純粋なチャンスで、スレッド2はスレッド1よりも早くロックによって取得されます。スレッドが互いの直後に作成されるため、これは完全に異なる可能性があります。言ったように:保証はありません。

2

ロック順序を保証するものではありません。Does lock() guarantee acquired in order requested?

また、あなたのコードでは、あなたが最初に「終わり」を持っていないためにあなたのforループの最後で終了するには、スレッドを待つ必要があります - あなたの場合キーを押すと、スレッドが実行中に終了し、予期しない動作が発生する可能性があります。

関連する問題