2016-07-31 1 views
-1

私はスレッドについての例を作成します
私は使用ロックがクリティカルセクションでのスレッドの中断を回避できると知っていますが、私は2つの質問があります。

1.私はThread.Sleepを使用すると私のプログラムが固まってしまいますか?
この例では、スリープを2つのスレッドに追加します。
私はコンソール出力がよりゆっくりとしたいので、間違っているかどうかを簡単に確認できます。
しかし、私がThread.Sleep()を使用すると、このプログラムが停止します!ロックセクションでthread.sleepを使用するC#

2.私はどのような状況でThread.Sleepを使用する必要がありますか?

よろしくお願いいたします。ありがとうございます。

class MyThreadExample 
{ 
    private static int count1 = 0; 
    private static int count2 = 0; 
    Thread t1; 
    Thread t2; 
    public MyThreadExample() { 
     t1 = new Thread(new ThreadStart(increment)); 
     t2 = new Thread(new ThreadStart(checkequal)); 
    } 
    public static void Main() { 

     MyThreadExample mt = new MyThreadExample(); 
     mt.t1.Start(); 
     mt.t2.Start(); 

    } 
    void increment() 
    { 
     lock (this) 
     { 
      while (true) 
      { 
       count1++; count2++; 
       //Thread.Sleep(0); stuck when use Sleep! 
      } 
     } 
    } 
    void checkequal() 
    { 
     lock (this) 
     { 
      while (true) 
      { 
       if (count1 == count2) 
        Console.WriteLine("Synchronize"); 
       else 
        Console.WriteLine("unSynchronize"); 
       // Thread.Sleep(0); 
      } 
     } 
    } 
} 
+0

のThread.sleepための解説(0):http://stackoverflow.com/questions/3257708/thread-sleep0-what-is-通常の動作 –

+0

しかし、もし私がThread.Sleep(10/100/1000 ...)を使用してもまだまだ立ち往生します – AHao

+0

あなたのプログラムは常に立ち往生するでしょう。スタックされた場所は完全にランダムですが、スレッドの1つが最初にロックに入り、もう1つのスレッドがロックに入ることはありません。ジッターがコードをより速く生成できるので、Sleep()呼び出しを使わずに「同期」することが多少ありそうです。もちろん、count1とcount2の値は決して変更されません。これがまだ明白でないときにスレッドを使用しないでください。もっと徹底的に勉強したいと思うでしょう。 –

答えて

0

以下のコードをご覧ください。 lock(this)を使用しないでください。代わりにlock(syncObj)を使用することをお勧めします。クリティカルセクション(例:変数のみ)をロックし、ループ全体をロックしないでください。メソッドMainで、最後に待機するものをConsole.Read()に追加します。そうでない場合、アプリケーションは停止しています。これはThread.Sleepの有無にかかわらず動作します。上のコードでは、スレッドは「Increment」または「Checkequal」と入力され、ロックは決して解放されません。その理由は、それはIncrementまたはCheckequalでのみ動作し、両方では動作しません。

internal class MyThreadExample 
    { 
    private static int m_Count1; 
    private static int m_Count2; 
    private readonly object m_SyncObj = new object(); 
    private readonly Thread m_T1; 
    private readonly Thread m_T2; 

    public MyThreadExample() 
    { 
     m_T1 = new Thread(Increment) {IsBackground = true}; 
     m_T2 = new Thread(Checkequal) {IsBackground = true}; 
    } 

    public static void Main() 
    { 
     var mt = new MyThreadExample(); 
     mt.m_T1.Start(); 
     mt.m_T2.Start(); 
     Console.Read(); 
    } 

    private void Increment() 
    { 
     while (true) 
     { 
     lock (m_SyncObj) 
     { 
      m_Count1++; 
      m_Count2++; 
     } 
     Thread.Sleep(1000); //stuck when use Sleep! 
     } 
    } 

    private void Checkequal() 
    { 
     while (true) 
     { 
     lock (m_SyncObj) 
     { 
      Console.WriteLine(m_Count1 == m_Count2 ? "Synchronize" : "unSynchronize"); 
     } 
     Thread.Sleep(1000); 
     } 
    } 
    } 

スレッドは少し古いスタイルです。 .NETの初心者で、.NET 4.5以上を使用している場合は、Taskを使用します。ずっといい。 .NETのすべての新しいマルチスレッドをタスクに基づいており、非同期のように待っています:

public static void Main() 
{ 
    var mt = new MyThreadExample(); 
    Task.Run(() => { mt.Increment(); }); 
    Task.Run(() => { mt.Checkequal(); }); 
    Console.Read(); 
} 
+0

ありがとう、私は本当の重要なセクションは今理解していますが、なぜ私は "これ"の代わりに "syncObj"をロックするか尋ねるかもしれません?違いは何ですか?私は本でそれを読むが、私はその部分を本当に理解していない。 – AHao

+0

ロック(これ)についての説明、それが悪い理由:http://stackoverflow.com/questions/251391/why-is-lockthis-bad –

+0

ありがとう!ちなみに、Isbackgroundプロパティのような小さなエディションであなたの例をお寄せいただき、ありがとうございました。 – AHao

関連する問題