Static properties in static classes
Question regarding static variables in static classes.
If i have a static cla开发者_StackOverflowss 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?
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.
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.
精彩评论