这是从MSDN:
lock关键字可确保一个线程不会在代码的关键部分中输入,而另一个线程在关键部分中。

关键部分
是否必须与关键部分相同?

还是说:
lock关键字可确保一个线程不会输入由代码对象保护的任何关键部分,而另一个线程位于中由同一对象保护的任何关键部分。 ?

    class Program
{
    static void Main(string[] args)
    {
        TestDifferentCriticalSections();

        Console.ReadLine();
    }

    private static void TestDifferentCriticalSections()
    {
        Test lo = new Test();

        Thread t1 = new Thread(() =>
        {
            lo.MethodA();
        });
        t1.Start();

        Thread t2 = new Thread(() =>
        {
            lo.MethodB();
        });
        t2.Start();
    }
}

public class Test
{
    private object obj = new object();

    public Test()
    { }

    public void MethodA()
    {
        lock (obj)
        {
            for (int i = 0; i < 5; i++)
            {
                Thread.Sleep(500);
                Console.WriteLine("A");
            }
        }
    }

    public void MethodB()
    {
        lock (obj)
        {
            for (int i = 0; i < 5; i++)
            {
                Thread.Sleep(500);
                Console.WriteLine("B");
            }
        }
    }
}

最佳答案

这个问题的措词困惑,到目前为止,答案也不是特别清楚。让我将这个问题重新表述为几个问题:



没有。例如:

static readonly object lock1 = new object();
static readonly object lock2 = new object();
static int counter = 0;
static object M()
{
    int c = Interlocked.Increment(ref counter);
    return c % 2 == 0 ? lock1 : lock2;
}

...
lock(M()) { Critical(); }

两个线程有​​可能同时位于lock语句的主体中,因为lock语句锁定在两个不同的对象上。线程Alpha可以调用M()并获取lock1,然后线程Beta可以调用M()并获取lock2。



是的。如果你有:
static readonly object lock1 = new object();
...
lock(lock1) { Critical(); }

那么线程Alpha可以获取该锁,并且线程Beta将阻塞,直到在进入锁体之前该锁可用为止。



是的。如果你有:
static readonly object lock1 = new object();
...
static void X()
{
    lock(lock1) { CriticalX(); }
}
static void Y()
{
    lock(lock1) { CriticalY(); }
}

然后,如果线程Alpha在X中并获得了锁,而线程Beta在Y中,则线程Beta将阻塞,直到进入锁体之前该锁可用。



引起注意的事实是,等待线程可能位于锁体内。您可以使用Monitor.Wait方法“暂停”锁体内的线程,并允许被阻塞的线程变为 Activity 状态并输入该锁体(或锁定同一对象的其他锁体)。等待线程将保持其“等待”状态,直到产生脉冲。在脉冲之后的某个时间,它重新加入“就绪”队列并阻塞,直到锁中没有“ Activity ”线程为止。然后,它从停止的位置恢复。

10-06 02:33