tags:

views:

107

answers:

3

Question regarding static variables in static classes.

If i have a static class and set the value of a property in it, publically exposed, is the value of this variable set for all instances of the class? So if thread 1 sets the value of property to 999, is the value set also for thread 2 to 999?

+7  A: 

Yes, it is. There is only one copy of the static class' fields inside an AppDomain.

You should however take synchronization into account. If thread 1 sets (writes to) the variable and thread 2 reads it at the same time, you may get unexpected results because it's possible that one write operation is actually divided into multiple processor instructions.

Suppose you set the value of a long. This is a 64 bit value and writing it involves at least 2 processor instructions (on a 32-bit machine). Theoretically it's possible that a read of the same long variable is scheduled between the two write instructions, leading to unexpected behavior.

Ronald Wildenberg
Strictly, there is no *instance* of the static class, but there is a single copy of each static field
Marc Gravell
You're right. Thanks for the additional info. I've updated my answer.
Ronald Wildenberg
@Marc: Yes, but... the OP *did* say (confusingly), "is the value of this variable set for all instances of the class?" So I'm guessing the OP actually just has a regular class and is talking about a static property. Either that or misused the word "instances."
Dan Tao
A: 

Others already gave the correct answer. I like to add the notion of thread safety. It is possible for other threads to see the old value for 'a while' after a thread has updated this value. If this behavior is unwanted, please synchronize the access to this property.

Steven
+1  A: 

Just to add to the discussion (why not?): yes, a static property is shared across all instances of a class, regardless of thread (unless the backing field is marked ThreadStatic, that is!). But yes, there are potential multithreading issues you have to face when dealing with such properties. Here's the scenario I think others are getting at.

Consider this code:

int x = MyClass.StaticProperty;
MyClass.StaticProperty = x + 1;

The preceding is a very simple example of where a race condition could cause two threads to perform what is supposed to be two indivisible actions, but instead ends up being effectively a single action.

To illustrate:

Thread 1                        Thread 2
int x = MyClass.StaticProperty;                                 // Let's say
                                int x = MyClass.StaticProperty; // this is 1.  
MyClass.StaticProperty = x + 1;                                 // OK, so x is
                                MyClass.StaticProperty = x + 1; // now... 2.

Do you see the problem? Two threads might both read the property's value before either one writes to it; and the value being written to it is dependent on the value read, which was identical for both threads!

In simple scenarios like the one above, there is a handy class provided in the System.Threading namespace that can make multithreaded reads/writes fairly painless to implement: Interlocked. For example to increment StaticProperty above in a thread-safe way, you might update MyClass as follows:

class MyClass
    static int _staticProperty;
    public static int StaticProperty
    {
        get { return _staticProperty; }
    }

    public static int IncrementProperty()
    {
        // increments _staticProperty ATOMICALLY
        // and returns its previous value
        return Interlocked.Increment(_staticProperty);
    }
}

In more complex scenarios (i.e., when you're not simply modifying plain numerical fields in a straightforward way), you may need to devise your own synchronization strategy, the most common of which is to have a designated lock object and simply lock on it for every operation you want to behave atomically.

Dan Tao