我的问题部分受到Eric Lippert撰写的文章的启发: http://blogs.msdn.com/ericlippert/archive/2009/10/19/what-is-this-thing-you-call-thread-safe.aspx
使用Eric的多个线程访问的Queue类示例。如果我有两个不同的代码片段来访问队列:
class MyThreadTest {
private static Object myThreadLock = new Object();
void MyDequeue() {
Object myLock = new Object();
lock (myLock) {
if (!queue.IsEmpty()) { queue.DeQueue(); }
}
}
Object MyPeek() {
lock (myThreadLock) {
if (!queue.IsEmpty()) { return queue.Peek(); }
}
}
}
两个线程在大约相同的时间访问MyDequeue()是否会受到锁定,而另一个线程在另一个线程之前获得锁定?或者两个线程是否都有不同的锁定对象,因为它们是在本地范围内声明的?如果是后者,将myLock对象声明为静态成员修复此问题?
如果MyThreadLock在MyDequeue中使用而不是本地myLock,那么两个线程(一个访问MyDequeue而另一个访问MyPeek)是否会尊重静态myThreadLock?
有很多我不确定,但我想知道锁是否锁定了一段代码,或者锁是否锁定了对象,以便使用该锁的所有代码段都被“打开”和“关闭”作为一个。
如果上面的代码中有任何其他细微之处,请指出它们,因为我对此过程非常天真。
答案 0 :(得分:3)
显示的代码是错误的。锁定局部变量(myLock
)总是无用的。
DeQueue()
也需要使用myThreadLock
,是的,这意味着它正在与Peek()
竞争访问权限。它应该,队列上的所有操作都应该使用相同的对象来锁定。