C #: question about thread safety for member variables

Can anyone explain why the threading examples will always make an object (specifically a member variable) static if it needs to be accessed by multiple threads?

My problem is that creating a member variable means it will be shared by all other instances of the class. Sometimes I find that I would like multiple threads within a class to "touch" a member variable, but at the same time allow each object to have its own copy.

Would the answer to accomplishing what I mentioned just replace:

  • Using the volatile keyword
  • Using a lock (object)
+2


source to share


2 answers


If you want each thread to use the same member variable, but also maintain a separate copy, you have a contradiction. Either they use the same variable or they don't. If I don't understand you correctly.

Having said that, if you really want a static field that can be accessed by multiple threads, each one storing its own private value, you can use the attribute ThreadStatic

. This attribute ensures that the static field is closed for each thread ("thread-local" as it is commonly called).

[ThreadStatic]
private static bool s_threadHasDoneItsWork;

      

Please note, you cannot initialize a local static field of a stream through a static constructor or directly like static type field = value

. (The compiler won't complain, but it won't work as expected.)




volatile

tells the current time that the field (static or not) should always be accessed directly from your main memory, so you don't need to use locks or memory locks to keep threads and cores synchronized. This is always relevant, so to speak, while other fields can still wait for the processor's memory cache to sync with your main memory.

But this is precisely the limit of what it does: only access that particular field. Once you have read it, the value is decayed again, so never think about doing something like volatileField ++ (which means "read volatileField, add it to the value just read, set volatileField", not "increment volatileField ", you need to use a class Interlocked

for this, which is much more expensive).

The safe way to use volatile fields is reading them directly, but when you change them, use a locking mechanism before you read or write them. (The only sensible exception I can think of is a boolean flag like "I'm done now."

The practical use of flying fields is, unsurprisingly, very limited. Stick with simple blocking; the keyword lock

and the corresponding class methods Monitor

respect the synchronization of one user and memory (as soon as you enter and exit the lock).

+3


source


There is nothing that requires the member variables to be static for streaming.

Most of the examples use a static variable, especially as they try to show how to synchronize data between two separate threads. If you want to do this, you must have a value available for both threads. Static variables are the easiest option since they are available everywhere.



You can also easily pass a class reference to your thread and have that thread, and your main thread is a non-static member variable. However, you need to provide a good locking / synchronization mechanism since you will have two threads sharing one instance of the class.

+8


source







All Articles