繁体   English   中英

C#-使用监视器

[英]C# - using Monitor

我正在尝试了解Monior.Wait和Monitor.Pulse的工作方式。 作为练习,我编写了以下程序。 我期望在m1之前先打印m2。

原理:如果m1首先获取锁,它将等待obj并释放锁。 因此,不应在m2之前打印m1。 如果m2取得了锁,则无论如何都会先打印m2。

但是我观察到的是完全不同的:当我正常运行该程序时,只有m1会被打印,并且此后它会保持静音而不会终止..也许程序陷入了某个循环。 为了分析它,当我在调试模式下运行程序时,得到了预期的行为。

有人可以解释一下这里发生了什么吗? 另外,编码此代码以获得预期行为的正确方法是什么?

class Program
{
    static object obj = new object();
    static void m1()
    {
        lock(obj)
        {
            Monitor.Enter(obj);
            Console.WriteLine("m1");
        }
    }

    static void m2()
    {
        lock (obj)
        {
            Console.WriteLine("m2");
            Monitor.Pulse(obj);

        }
    }
    static void Main(string[] args)
    {
        Thread t1 = new Thread(m1);
        Thread t2 = new Thread(m2);
        t1.Start();
        t2.Start();                        
    }
}

lock语句在后台使用Monitor.EnterMonitor.Exit

所以你的代码

static void m1()
{
    lock(obj)
    {
        Monitor.Enter(obj);
        Console.WriteLine("m1");
    }
}

实际上获得两次但只能释放一次 因此,如果m1m2之前获得了锁,则obj上的锁将永远不会释放,而m2将永远等待。

证明

(快捷方式:在rextester上运行代码)

如下更改m1

static void m1()
{
    lock(obj)
    {
        Monitor.Enter(obj);
        Console.WriteLine("m1");
    }

    Console.WriteLine("m1 has lock on obj: ", Monitor.IsEntered(obj));
}

并将其打印出来(好吧,..仅在m1首先获得锁的情况下!):

m1

m1已锁定obj:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM