2010-09-13 12 views
6

Frage zu statischen Variablen in statischen Klassen.Statische Eigenschaften in statischen Klassen

Wenn ich eine statische Klasse habe und den Wert einer Eigenschaft, die öffentlich verfügbar gemacht wird, festlegen, wird der Wert dieser Variablen für alle Instanzen der Klasse festgelegt? Wenn also Thread 1 den Wert von property auf 999 setzt, ist der Wert auch für Thread 2 auf 999 gesetzt?

Antwort

11

Ja, ist es. Es gibt nur eine Kopie der Felder der statischen Klasse in einer AppDomain.

Sie sollten jedoch die Synchronisation berücksichtigen. Wenn Thread 1 die Variable festlegt (schreibt) und Thread 2 sie gleichzeitig liest, erhalten Sie möglicherweise unerwartete Ergebnisse, weil es möglich ist, dass eine Schreiboperation tatsächlich in mehrere Prozessorbefehle unterteilt ist. Geben Sie den Wert long ein. Dies ist ein 64-Bit-Wert und das Schreiben umfasst mindestens 2 Prozessoranweisungen (auf einer 32-Bit-Maschine). Theoretisch ist es möglich, dass ein Lesen der gleichen long Variable zwischen den beiden Schreibanweisungen geplant wird, was zu unerwartetem Verhalten führt.

+3

Genau genommen gibt es keine * Instanz * der statischen Klasse, aber es gibt eine einzige Kopie jedes statischen Felds –

+0

Sie haben Recht. Danke für die zusätzlichen Informationen. Ich habe meine Antwort aktualisiert. –

+0

@Marc: Ja, aber ... das OP * hat * (verwirrend) gesagt, "ist der Wert dieser Variablen für alle Instanzen der Klasse gesetzt?"Also ich vermute, das OP hat eigentlich nur eine reguläre Klasse und spricht von einer statischen Eigenschaft. Entweder das oder missbrauchte das Wort" Instanzen ". –

2

Nur zur Diskussion hinzufügen (warum nicht?): Ja, eine static Eigenschaft ist für alle Instanzen einer Klasse unabhängig vom Thread freigegeben (es sei denn, das Hintergrundfeld ist mit markiert!). Aber ja, es gibt potentielle Multithreading-Probleme, mit denen Sie konfrontiert werden, wenn Sie mit solchen Eigenschaften umgehen. Hier ist das Szenario, von dem ich denke, dass andere es verstehen.

Betrachten Sie diesen Code:

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

Die vorstehenden ist ein sehr einfaches Beispiel, wo eine Race-Bedingung zwei Threads dazu führen könnten, auszuführen, was soll zwei untrennbare Aktionen sein, sondern endet effektiv zu sein eine einzelne Aktion.

Zur Veranschaulichung:

 
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. 

Sehen Sie das Problem? Zwei Threads könnten beide lesen der Wert der Eigenschaft vor entweder schreibt zu ihm; und der Wert, der darauf geschrieben wird, hängt vom gelesenen Wert ab, der für beide Threads identisch war!

In einfachen Szenarien wie die oben, eine praktische Klasse dort im System.Threading Namensraum zur Verfügung gestellt, die multithreaded machen liest/schreibt ziemlich schmerzlos zu implementieren: Interlocked. Zum Beispiel StaticProperty oben in einem Thread-sichere Art und Weise zu erhöhen, könnten Sie MyClass wie folgt aktualisieren:

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 komplexeren Szenarien (dh wenn du dich nicht einfach schlicht numerische Felder auf einfache Art und Weise zu verändern), Sie müssen möglicherweise Ihre eigene Synchronisierungsstrategie entwickeln, von denen die gebräuchlichste ein festgelegtes Sperrobjekt und einfach lock für jede Operation ist, die Sie sich atomar verhalten wollen.

Verwandte Themen