Was macht @synchronized () als Singleton-Methode in Ziel C?

85

Ich habe gerade eine Singleton-Methode erstellt und möchte wissen, was die Funktion @synchronized()tut, da ich sie häufig verwende, aber die Bedeutung nicht kenne.

max_
quelle

Antworten:

117

Es deklariert einen kritischen Abschnitt um den Codeblock. @synchronizedGarantiert in Multithread-Code, dass jeweils nur ein Thread diesen Code im Block ausführen kann.

Wenn Sie nicht wissen, was es tut, ist Ihre Anwendung wahrscheinlich nicht multithreaded und Sie müssen sie wahrscheinlich nicht verwenden (insbesondere wenn der Singleton selbst nicht threadsicher ist).


Bearbeiten: Hinzufügen weiterer Informationen, die nicht in der ursprünglichen Antwort von 2011 enthalten waren.

Die @synchronizedDirektive verhindert, dass mehrere Threads in einen Codebereich eintreten, der durch eine @synchronizedDirektive geschützt ist , die auf dasselbe Objekt verweist . Das an die @synchronizedDirektive übergebene Objekt ist das Objekt, das als "Sperre" verwendet wird. Zwei Threads können sich in demselben geschützten Codebereich befinden, wenn ein anderes Objekt als Sperre verwendet wird, und Sie können auch zwei völlig unterschiedliche Codebereiche mit demselben Objekt wie die Sperre schützen.

Wenn Sie zufällig nilals Sperrobjekt übergeben werden, wird überhaupt keine Sperre vorgenommen.

John Calsbeek
quelle
14
Ein paar wichtige Punkte: 1) Wenn Sie einen Null-Zeiger verwenden @synchronized, geschieht nichts - Sie bleiben ungeschützt. 2) @synchronizedist langsam .
Hot Licks
Diese Antwort ist irreführend und sollte nicht die akzeptierte Antwort sein. Obwohl das, was darin steht, manchmal korrekt ist (solange das an synhronized übergebene Token in allen Threads dasselbe Objekt ist), ist es irreführend unvollständig. Durch die Synchronisierung wird verhindert, dass eine beliebige Anzahl zugeordneter Codeabschnitte gleichzeitig ausgeführt wird, nicht nur "dieser Code im Block". Der zu synchronisierende Parameter bestimmt effektiv, welche Codeabschnitte (oder "Blöcke", wie die Antwort sie nennt) vor gleichzeitigem Zugriff geschützt sind.
Arda
@Arda Du hast vollkommen recht. Ich habe ein bisschen mehr Informationen und einen Link zu einer Apple-Dokumentation über hinzugefügt @synchronized.
John Calsbeek
@ JohnCalsbeek, die Antwort sieht jetzt viel besser aus. Daumen hoch von mir.
Arda
@HotLicks interessant, um darauf hinzuweisen, aber es wäre noch besser gewesen, kurz zu sagen, was die Alternativen (Links?)
Sein
43

Aus der Apple-Dokumentation hier und hier :

Die @ synchronisierte Direktive ist eine bequeme Möglichkeit, Mutex-Sperren im laufenden Betrieb in Objective-C-Code zu erstellen. Die @ synchronisierte Direktive macht das, was jede andere Mutex-Sperre tun würde - sie verhindert, dass verschiedene Threads gleichzeitig dieselbe Sperre erhalten.

Die Dokumentation bietet eine Fülle von Informationen zu diesem Thema. Es lohnt sich, sich die Zeit zu nehmen, um es durchzulesen, insbesondere angesichts der Tatsache, dass Sie es verwendet haben, ohne zu wissen, was es tut.

csano
quelle
26

Die @synchronizedDirektive ist eine bequeme Möglichkeit, Mutex-Sperren im laufenden Betrieb in Objective-C- Code zu erstellen .

Die @synchronizedDirektive macht das, was jede andere Mutex-Sperre tun würde - sie verhindert, dass verschiedene Threads gleichzeitig dieselbe Sperre erhalten.

Syntax:

 @synchronized(key) 
 { 
  // thread-safe code 
 }

Beispiel:

 -(void)AppendExisting:(NSString*)val
{
  @synchronized (oldValue) {
      [oldValue stringByAppendingFormat:@"-%@",val];
  }
}

Jetzt ist der obige Code vollkommen threadsicher. Jetzt können mehrere Threads den Wert ändern.

Das Obige ist nur ein obskures Beispiel ...

Durai Amuthan.H
quelle
3
Sollte es nicht @synchronized (oldValue) sein?
Joel
Oder sogar @synchronized(val, oldValue) { ... }?
Valentin Shergin
Ich bin mir nicht sicher, ob ich jemals ein Schema gesehen habe, das "perfekt threadsicher" war. Zumindest müssen Sie wissen, was Sie tun, und nicht nur blind Code von irgendwoher kopieren.
Hot Licks
Aber ich nehme an, der obige Code ist doch "perfekt threadsicher", da er absolut nichts bewirkt.
Hot Licks
6

@synchronized block übernimmt automatisch das Sperren und Entsperren für Sie . @synchronize Sie haben eine implizite Sperre für das Objekt, das Sie zum Synchronisieren verwenden. Hier finden Sie eine sehr informative Diskussion zu diesem Thema. Folgen Sie bitte Wie wird @synchronized in Objective-C gesperrt / entsperrt?

abdus.me
quelle
-2

@synchronizedist thread safeMechanismus. Der in diese Funktion geschriebene Code wird zu dem Teil critical section, für den jeweils nur ein Thread ausgeführt werden kann.

@synchronizeWendet die Sperre implizit an, während NSLocksie explizit angewendet wird.

Es gewährleistet nur die Gewindesicherheit, garantiert dies jedoch nicht. Was ich meine ist, dass Sie einen erfahrenen Fahrer für Ihr Auto einstellen, aber es garantiert nicht, dass das Auto keinen Unfall erleidet. Die Wahrscheinlichkeit bleibt jedoch am geringsten.


quelle
2
Das ist absolut falsch. dispatch_once macht NICHT dasselbe wie @syncrhonized, es kann NUR unter der Zuweisung eines Singletons ein Ersatz sein.
Jugutier