Frage

Ich bin ein Java-Programmierer und ich weiß, ein paar Dinge über Einfädeln int Java.

In Java kann ich eine Methode sperren, indem synchronisierte Schlüsselwort:

private int a;
private int b;
private int c;
private synchronized void changeVars()
{
  a = 4;
  b = 2;
  c = a+b;
}

ich in Msdn gesucht und sah, dass es ein paar Spielsachen in c # sind mit Fäden zu spielen. Wie Monitor.Enter, Monitor.Exit, Schloss oder ein fortgeschrittenes ein Mutex.

Aber was ich brauche, ist eine Methode zu synchronisieren. Was ist das Äquivalent davon in c #?

Vielen Dank im Voraus.

War es hilfreich?

Lösung

So etwas wie dieses mayhaps:

using System.Runtime.CompilerServices;

...

private int a;
private int b;
private int c;

[MethodImpl(MethodImplOptions.Synchronized)]
private void changeVars()
{
  a = 4;
  b = 2;
  c = a+b;
}

Andere Tipps

Es gibt keine direkte Entsprechung in C #, aber man kann mit diesem das gleiche tun:

private readonly object changeVarsLockObject = new object();

private void changeVars()
{
  lock(changeVarsLockObject)
  {
    a = 4;
    b = 2;
    c = a+b;
  }
}

Just klar zu sein - eine Methode in Java synchronisiert erklärt erfordert, dass der Anrufer den Monitor hält auf der Objekt , dass das Verfahren wurde am genannt (das Class Objekt für statische Methoden ist)

So sagen Sie „ein Verfahren sperren“ ist irreführend, da Sie ganz nicht, dass die Methode sperren (die gleiche Methode kann noch auf andere Instanz-Objekte genannt werden), und sperren Sie mehr als Verfahren (kein anderer Bit-Code, der das Zielobjekt des Monitors, einschließlich anderer Methoden synchronisiert oder explizite akquiriert der es erfordert, kann laufen gleichzeitig).

Die Synchronisation ist hart , und im Idealfall brauchen Sie mehr als „ein paar Dinge“, darüber zu wissen, ob Sie Deadlocks und Sichtbarkeit Probleme vermeiden möchten, die so gut wie nie während des Tests erscheinen, oder förderlich sind zu Debuggen . ein möglicherweise unvollständiges Verständnis der Synchronisation in einer Sprache machen, und versucht, sie mit unterschiedlichen Grundelementen in einer anderen Sprache zu übertragen und wahrscheinlich ein anderes Speichermodell ist ein Rezept für eine Katastrophe.

So, während dies nicht die Antwort Einzeiler ist, dass Sie suchen, werde ich behaupten, dass jede Einzeiler Antwort zum Scheitern verurteilt ist, ohne das Wissen des gesamten Ökosystems zum Scheitern verurteilt, es zu sichern. So sollten Sie ein gutes Buch lesen / tutorial auf der Synchronisation in C #, anstatt zu versuchen, Ihr Java-Erfahrung Stichwort nach Stichwort zu übersetzen.

das direkte Äquivalent davon verwendet Sperre (this):

private void ChangeVars()
{
    lock (this) {
        a = 4;
        b = 2;
        c = a+b;
    }
}

oder in der Tat mit den MethodImplAttribute wie von R. Bemrose, was dasselbe ist:

[MethodImpl(MethodImplOptions.Synchronized)]
private void ChangeVars()
{
    a = 4;
    b = 2;
    c = a+b;
}

... ist es jedoch nicht öffentlich sichtbares Objekt verwenden zum Sperren zu empfehlen, da jemand anderes könnte genauso gut entscheiden, es als Sperrobjekt zu verwenden, so dass eine bessere Übersetzung wäre:

private object monitor = new object();
private void ChangeVars()
{
    lock (monitor) {
        a = 4;
        b = 2;
        c = a+b;
    }
}

Die bevorzugte Lösung ist die Methode Körper in einer lock Anweisung zu wickeln.

internal class Foo
{
   private Object lockObject = new Object();

   private void ChangeVars()
   {
      lock (this.lockObject)
      {
         // Manipulate the state.
      }
   }
}

Sie können die deklarative Synchronisation verwenden, auch, aber dies hat den offensichtlichen Nachteil, dass Sie von ContextBoundObject und alle dekoriert Methoden mit der Synchronization Attribut das gleiche Sperrobjekt Begrenzung der Sperrgranularität teilen.

internal class Foo : ContextBoundObject
{
   [Synchronization]
   private void ChangeVars()
   {
      // Manipulate the state.
   }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top