在锁定部分C#中使用thread.sleep

时间:2016-07-31 07:43:33

标签: c# multithreading

我创建一个关于线程的例子,
我知道使用锁可以避免在关键部分暂停线程,但我有两个问题。

1.如果我使用Thread.Sleep,为什么我的程序会卡住?
在这个例子中,我将sleep添加到两个线程。
因为我希望控制台输出更慢,所以我可以很容易地看出是否有任何错误。
但是如果我使用Thread.Sleep()那么这个程序就会卡住!

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

1 个答案:

答案 0 :(得分:0)

请查看以下代码。永远不要使用lock(this),而是使用lock(syncObj),因为你可以更好地控制它。仅锁定临界区(例如:仅变量)并且不要锁定整个while循环。在方法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中的所有新多线程都基于Task,如异步等待:

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