From: Jon Skeet [C# MVP] <
[email protected]>
Subject: Re: volatile keyword causes error when compiling
Date: Sat, 25 Sep 2004 07:27:05 +0100
Brian Smith said:
While lock can be very useful, it does nothing to help this particular
situation.
There should be. Acquiring a lock involves a volatile read, and
releasing a lock involves a volatile write.
There is no thread safety issue here -- the CLR specification
guarantees that writes and reads to properly aligned variables of 32-bits
or less will always be atomic.
Atomicity is almost irrelevant here - stale data is the concern. They
are two very separate issues.
From what we have been told about this
scenario, it involves only one write and read to a small field. If more
than one field was getting modified or read and those operations needed to
take place atomically or in a particular order, then lock would be the
correct solution.
What Jim is concerned about is that a compiler might eliminate the read
entirely, not that it might take place out of order. The presence or
absence of a "lock" statement around the use of an object will not change
the code generation of either the C# or JIT compilers beyond adding a call
out to a Monitor method. The actual field access would be unchanged.
The field access could not be reordered to outside the lock statement,
due to the volatile read/write semantics of locks.
See
http://www.pobox.com/~skeet/csharp/threads/volatility.shtml for my
understanding of the topic.
Without the use of the "volatile" keyword, a compiler is technically
allowed to re-order memory accesses or delay them but it doesn't give
permission to eliminate the access completely unless the compiler can
really know that there is no other thread that has access to the object in
question and could modify it "behind its back." I promise you that the .NET
CF JIT compiler will never optimize out a field access to a globally
visible object and for the forseeable future it will not even delay or
otherwise complicate field accesses.
Of course, after all that "promising" and "guaranteeing" you should
look at the disclaimer I am told to put at the end of every post
Indeed. I think I'll stick to writing code which is guaranteed to be
thread-safe by the spec, which I assume the CF will still obey. If
nothing else, it means I can use the same coding models for the CF and
the desktop, which makes life simpler. If acquiring a lock turns out to
be a bottleneck in the code, I'll reconsider at that point with heavy
comments. It hasn't been in the past though.
(Most classes don't need to be thread-safe, of course, so this only
affects "boundary" classes.)