Does Monitor.Wait ensure that fields are re-read?

Posted by Marc Gravell on Stack Overflow See other posts from Stack Overflow or by Marc Gravell
Published on 2010-03-12T07:57:31Z Indexed on 2010/03/12 8:07 UTC
Read the original article Hit count: 198

Filed under:
|
|
|
|

It is generally accepted (I believe!) that a lock will force any values from fields to be reloaded (essentially acting as a memory-barrier or fence - my terminology in this area gets a bit loose, I'm afraid), with the consequence that fields that are only ever accessed inside a lock do not themselves need to be volatile.

(If I'm wrong already, just say!)

A good comment was raised here, questioning whether the same is true if code does a Wait() - i.e. once it has been Pulse()d, will it reload fields from memory, or could they be in a register (etc).

Or more simply: does the field need to be volatile to ensure that the current value is obtained when resuming after a Wait()?

Looking at reflector, Wait calls down into ObjWait, which is managed internalcall (the same as Enter).

The scenario in question was:

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
    }
}

Obviously I could just make it volatile, or I could move this out so that I exit and re-enter the Monitor every time it gets pulsed, but I'm intrigued to know if either is necessary.

© Stack Overflow or respective owner

Related posts about threading

Related posts about c#