Cui*_*崔鹏飞 20 c# multithreading locking block critical-section
这来自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");
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
Eri*_*ert 64
问题是措辞混乱,到目前为止的答案也不是特别清楚.让我把这个问题改成几个问题:
(1)lock语句是否确保一次锁定语句的主体中只有一个以上的线程?
不.例如:
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(); }
Run Code Online (Sandbox Code Playgroud)
两个线程可能同时位于lock语句的主体中,因为lock语句锁定了两个不同的对象.线程Alpha可以调用M()并获取lock1,然后线程Beta可以调用M()并获取lock2.
(2)假设我的lock语句总是锁定在同一个对象上,lock语句是否确保一次锁定体中只有一个"活动"线程?
是.如果你有:
static readonly object lock1 = new object();
...
lock(lock1) { Critical(); }
Run Code Online (Sandbox Code Playgroud)
然后线程Alpha可以获取锁定,线程Beta将阻塞,直到锁定可用,然后才能进入锁体.
(3)假设我有两个锁定语句,并且每次锁定语句都锁定在同一个对象上,锁定语句是否确保一次锁定的主体中只有一个"活动"线程?
是.如果你有:
static readonly object lock1 = new object();
...
static void X()
{
lock(lock1) { CriticalX(); }
}
static void Y()
{
lock(lock1) { CriticalY(); }
}
Run Code Online (Sandbox Code Playgroud)
然后,如果线程Alpha在X中并且获取锁定,并且线程Beta在Y中,则线程Beta将阻塞,直到锁定可用,然后才能进入锁体.
(4)你为什么把"主动"放在"恐慌报价"中?
提醒注意一个等待线程可能在锁体中的事实.您可以使用该Monitor.Wait方法"暂停"锁定主体中的线程,并允许阻塞的线程变为活动状态并进入该锁定主体(或锁定同一对象的其他锁定主体).等待线程将保持其"等待"状态,直到脉冲.在脉冲之后的某个时间,它重新加入"就绪"队列并阻塞,直到锁中没有"活动"线程.然后它从它停止的位置恢复.
你锁定了一个物体.如果另一个线程试图同时访问该对象标记的关键部分,它将阻塞,直到锁定被移除/完成.
例:
public static object DatabaseLck= new object();
lock (DatabaseLck) {
results = db.Query<T>(query).ToList();
}
Run Code Online (Sandbox Code Playgroud)
要么
lock (DatabaseLck) {
results = db.Query<T>(string.Format(query, args)).ToList();
}
Run Code Online (Sandbox Code Playgroud)
这些代码块中的任何一个都不能同时运行,因为它们使用相同的锁对象.如果您为每个锁定对象使用了不同的锁定对象,则它们可以同时运行.
| 归档时间: |
|
| 查看次数: |
9119 次 |
| 最近记录: |