wake-up-neo.net

C # -Version von Javas synchronisiertem Schlüsselwort?

Hat c # eine eigene Version des Schlüsselworts Java "synchronized")?

Das heißt in Java kann entweder für eine Funktion, ein Objekt oder einen Codeblock angegeben werden, wie folgt:

public synchronized void doImportantStuff() {
   // dangerous code goes here.
}

oder

public void doImportantStuff() {
   // trivial stuff

   synchronized(someLock) {
      // dangerous code goes here.
   }
}
293
Soraz

Erstens: Die meisten Klassen müssen niemals threadsicher sein. Verwenden Sie YAGNI : Wenden Sie Thread-Sicherheit nur an, wenn Sie wissen, dass Sie sie tatsächlich verwenden werden (und testen Sie sie).

Für Sachen auf Methodenebene gibt es [MethodImpl]:

[MethodImpl(MethodImplOptions.Synchronized)]
public void SomeMethod() {/* code */}

Dies kann auch für Accessoren (Eigenschaften und Ereignisse) verwendet werden:

private int i;
public int SomeProperty
{
    [MethodImpl(MethodImplOptions.Synchronized)]
    get { return i; }
    [MethodImpl(MethodImplOptions.Synchronized)]
    set { i = value; }
}

Beachten Sie, dass feldähnliche Ereignisse standardmäßig synchronisiert werden , während automatisch implementierte Eigenschaften nicht synchronisiert werden :

public int SomeProperty {get;set;} // not synchronized
public event EventHandler SomeEvent; // synchronized

Persönlich mag ich die Implementierung von MethodImpl nicht, da sie this oder typeof(Foo) sperrt - was gegen die Best Practice verstößt. Die bevorzugte Option ist die Verwendung eigener Sperren:

private readonly object syncLock = new object();
public void SomeMethod() {
    lock(syncLock) { /* code */ }
}

Beachten Sie, dass für feldähnliche Ereignisse die Sperrimplementierung vom Compiler abhängig ist. In älteren Microsoft-Compilern ist es eine lock(this)/lock(Type) - jedoch in neueren Compilern verwendet es Interlocked updates - also threadsicher ohne die bösen teile.

Dies ermöglicht eine genauere Verwendung und die Verwendung von Monitor.Wait/Monitor.Pulse Usw. für die Kommunikation zwischen Threads.

Ein verwandter Blogeintrag (später überarbeitet ).

444
Marc Gravell
static object Lock = new object();

lock (Lock) 
{
// do stuff
}
54
Jan Gressmann

Hat c # eine eigene Version des Schlüsselworts Java "synchronized")?

Nein. In C # geben Sie explizit lock Ressourcen an, die Sie synchron über asynchrone Threads hinweg bearbeiten möchten. lock öffnet einen Block; Es funktioniert nicht auf Methodenebene.

Der zugrunde liegende Mechanismus ist jedoch ähnlich, da lock durch Aufrufen von Monitor.Enter (und anschließend Monitor.Exit) zur Laufzeit. Java funktioniert laut Sun-Dokumentation auf die gleiche Weise.

39
Konrad Rudolph

Beachten Sie, dass bei vollständigen Pfaden die Zeile: [MethodImpl(MethodImplOptions.Synchronized)] so aussehen sollte

[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.Synchronized)]

7
Traubenfuchs

Sie können stattdessen die Anweisung lock verwenden. Ich denke das kann nur die zweite Version ersetzen. Denken Sie auch daran, dass sowohl synchronized als auch lock ein Objekt bearbeiten müssen.

5
James