人们普遍接受(我相信!) alock
将强制重新加载字段中的任何值(本质上充当内存屏障或栅栏 - 恐怕我在这方面的术语有点松散),结果那些只在 a 内部访问过lock
的字段本身不需要是volatile
.
(如果我已经错了,就说吧!)
这里提出了一个很好的评论,质疑如果代码执行 a 是否也是如此Wait()
- 即一旦它被Pulse()
d,它是否会从内存中重新加载字段,或者它们是否可以在寄存器中(等)。
或者更简单地说:该字段是否需要volatile
确保在 a 之后恢复时获得当前值Wait()
?
看着反射器,Wait
调用到ObjWait
,即managed internalcall
(与 相同 Enter
)。
有问题的场景是:
bool closing;
public bool TryDequeue(out T value) {
lock (queue) { // arbitrary lock-object (a private readonly ref-type)
while (queue.Count == 0) {
if (closing) { // <==== (2) access field here
value = default(T);
return false;
}
Monitor.Wait(queue); // <==== (1) waits here
}
...blah do something with the head of the queue
}
}
显然我可以成功,或者我可以将它移出,以便每次它被脉冲时volatile
我退出并重新进入,但我很想知道是否有必要。Monitor