If you want each thread to use the same member variable, but also maintain a separate copy, you've got a contradiction here. Either they use the same variable or they don't. Unless I'm not understanding you right.
Having said that, if you really need a static field to be accessed by multiple threads, each maintaining their own, private value, you can use the ThreadStatic
attribute. This attribute ensures that the static field will be private to each thread ("thread local" as it's usually called).
[ThreadStatic]
private static bool s_threadHasDoneItsWork;
Note that you cannot initialize a thread local static field through a static constructor or directly as static type field = value
. (The compiler won't complain, but it won't work properly.)
volatile
tells the runtime that the field (static or not) must always be accessed directly from your main memory, so you don't need to use locks or memory barriers to synchronize threads and cores. It's always up-to-date, so to speak, whereas other fields can still be waiting for your processor's memory cache to sync up with your main memory.
But that's exactly the limit of what it does: only access to that particular field. As soon as you've read it, the value is stale again, so don't ever think of doing something like volatileField++ (which means "read volatileField, add one to the value you've just read, set volatileField", and not "increment volatileField", you'll need to use the Interlocked
class for that, which is a lot more expensive).
A safe way to use volatile fields is reading them directly, but when you're modifying them, to use a locking mechanism before you either read or write them. (The only reasonable exception I can think of is a boolean flag like "I'm done now".)
The practical use of volatile fields is, not surprisingly, rather limited. Stick with simple locking; the lock
keyword, and the corresponding Monitor
class's methods take care of both the single user and memory synchronization (as soon as you enter and exit the lock).