Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Static properties in static classes

Tags:

c#

static

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?

like image 222
amateur Avatar asked Sep 13 '10 10:09

amateur


2 Answers

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.

like image 63
Ronald Wildenberg Avatar answered Oct 07 '22 19:10

Ronald Wildenberg


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.

like image 29
Dan Tao Avatar answered Oct 07 '22 19:10

Dan Tao