-1

I create an example about thread,
I know that use lock could avoid thread suspending at critical section, but I have two questions.

1.Why my program get stuck if I use Thread.Sleep?
In this example, I add sleep to two thread.
Because I wish the console output more slowly, so I can easily see if there's anything wrong.
But if I use Thread.Sleep() then this program will get stuck!

2.What situation should I use Thread.Sleep?

Thanks for your kind response, have a nice day.

    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);
            }
        }
    }
}
AHao
  • 7
  • 2
  • Explanation for Thread.Sleep(0) : http://stackoverflow.com/questions/3257708/thread-sleep0-what-is-the-normal-behavior –  Jul 31 '16 at 07:47
  • but stuck still happen if I use Thread.Sleep(10/100/1000...) – AHao Jul 31 '16 at 07:56
  • Your program will always get stuck. Where it gets stuck is completely random, one of the threads is going to enter the lock first and the other thread will never enter it. It is somewhat more likely to see "Synchronize" without the Sleep() call since the jitter can generate the code faster. But of course then the count1 and count2 values never change. Don't use threads when this isn't obvious yet, you'll want to study the subject much more thoroughly. – Hans Passant Jul 31 '16 at 13:42

1 Answers1

0

Please take a look at these following codes. Never use lock(this), instead use lock(syncObj) because you have better control over it. Lock only the critical section (ex.: only variable) and dont lock the whole while loop. In method Main, add something to wait at the end "Console.Read()", otherwise, your application is dead. This one works with or without Thread.Sleep. In your code above, your thread will enter "Increment" or "Checkequal" and the lock will never release. Thats why, it works only on Increment or Checkequal and never both.

  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);
      }
    }
  }

Thread is a little bit old style. If you are a beginner of .NET and using .NET 4.5 or above, then use Task. Much better. All new multithreading in .NET are based on Task, like async await:

public static void Main()
{
  var mt = new MyThreadExample();
  Task.Run(() => { mt.Increment(); });
  Task.Run(() => { mt.Checkequal(); });
  Console.Read();
}
  • Thanks, I understand what's the real critical section now, but may I ask why to lock "syncObj" instead of "this"? what's the different? Though I read that in books, but I don't really understand that part. – AHao Jul 31 '16 at 09:12
  • Better explanation about lock(this), why it is bad : http://stackoverflow.com/questions/251391/why-is-lockthis-bad –  Jul 31 '16 at 09:22
  • Thanks! By the way, thanks for your example with little edition, like Isbackground property, they helps me a lot. – AHao Jul 31 '16 at 09:26
  • If your application quit, background thread also quit. But foreground thread not. –  Jul 31 '16 at 09:33