1

考虑这段代码:

public class Test
{
        public void Print()
        {
            lock (this)
            {
                System.Threading.Thread.Sleep(10000);
                Console.WriteLine("Print");
            }
        }
        public static void Somthing()
        {
            Console.WriteLine("Somthing");
        }
}

print方法 Ilock中,该类Somthing是一个静态方法。我希望在那Somthing之后调用时PrintSomthing单独运行线程,因为我没有Test调用实例Somthing

private static void Main(string[] args)
{
     var test = new Test();
     test.Print();
     Test.Somthing();
}

但是当写上面的代码时,Test锁定然后调用Somthing

为什么编译器有这种行为?

4

2 回答 2

12

这里没有任何东西会导致使用另一个线程;为什么会呢?你的代码:

  • 创建一个实例Test
  • 在该实例上 调用 ( callvirt)Print
    • 它需要Monitor锁定自身(不是一个好主意,顺便说一句)
    • 睡眠 10 秒
    • 向控制台写入一行
    • 释放Monitor
  • 调用 ( call) 静态Something方法
    • 将一行写入控制台

不需要额外的线程。我应该强调:即使您没有释放Monitor锁(通过Monitor.Enter不使用 a Monitor.Exit),它对于线程的工作方式也是一样的;再次:lock 不创建线程

A在持续时间内lock简单地停止(阻止)其他线程lock对同一对象进行处理——它创建了一个互斥区域。它不创建线程。

于 2013-07-29T07:52:02.940 回答
3

lock只是避免另一个线程访问要访问的块内的代码,直到句柄返回。在您的情况下,您实际上有一个线程(外部锁)。lock 语句中的代码不会被任何东西锁定。代码同步执行意味着 - 线程休眠指定的时间,然后调用Something方法。

于 2013-07-29T07:55:36.433 回答