这是从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 ”线程为止。然后,它从停止的位置恢复。