Cosa fa @synchronized () come metodo singleton nell'obiettivo C?


88

Ho appena creato un metodo singleton e vorrei sapere cosa fa la funzione @synchronized(), poiché la uso frequentemente, ma non ne conosco il significato.

Risposte:


119

Dichiara una sezione critica attorno al blocco di codice. Nel codice multithread, @synchronizedgarantisce che solo un thread possa eseguire quel codice nel blocco in un dato momento.

Se non sei a conoscenza di ciò che fa, probabilmente la tua applicazione non è multithread e probabilmente non hai bisogno di usarla (specialmente se il singleton stesso non è thread-safe).


Modifica: aggiunta di ulteriori informazioni che non erano nella risposta originale del 2011.

La @synchronizeddirettiva impedisce a più thread di entrare in qualsiasi regione di codice protetta da una @synchronizeddirettiva che fa riferimento allo stesso oggetto . L'oggetto passato alla @synchronizeddirettiva è l'oggetto utilizzato come "blocco". Due thread possono trovarsi nella stessa area di codice protetta se un oggetto diverso viene utilizzato come blocco ed è inoltre possibile proteggere due aree di codice completamente diverse utilizzando lo stesso oggetto del blocco.

Inoltre, se ti capita di passare nilcome oggetto di blocco, non verrà preso alcun blocco.


14
Un paio di punti importanti: 1) Se usi un puntatore zero in @synchronizedesso non fa nulla: rimani senza protezione. 2) @synchronizedè lento .
Hot Licks

Questa risposta è fuorviante e non dovrebbe essere la risposta accettata. Sebbene ciò che dice a volte sarebbe corretto (fintanto che il token passato a synhronized è lo stesso oggetto in tutti i thread), è fuorviante incompleto. sincronizzato impedisce l'esecuzione contemporanea di un numero qualsiasi di sezioni di codice associate, non solo "quel codice nel blocco". Il parametro da sincronizzare determina efficacemente quali sezioni di codice (o "blocchi" come le chiama la risposta) sono protette dall'accesso simultaneo.
Arda

@Arda Hai perfettamente ragione. Ho aggiunto qualche informazione in più e un collegamento ad alcuni documenti Apple su @synchronized.
John Calsbeek

@JohnCalsbeek, la risposta sembra molto migliore ora. Pollice in alto da parte mia.
Arda

@HotLicks è interessante farlo notare, ma sarebbe stato ancora meglio dire brevemente quali potrebbero essere le alternative (link?)
itMaxence

43

Dalla documentazione Apple qui e qui :

La direttiva @synchronized è un modo conveniente per creare blocchi mutex al volo nel codice Objective-C. La direttiva @synchronized fa ciò che farebbe qualsiasi altro blocco mutex: impedisce a thread diversi di acquisire lo stesso blocco allo stesso tempo.

La documentazione fornisce numerose informazioni su questo argomento. Vale la pena dedicare del tempo a leggerlo, soprattutto dato che lo usi senza sapere cosa sta facendo.


27

La @synchronizeddirettiva è un modo conveniente per creare blocchi mutex al volo nel codice Objective-C .

La @synchronizeddirettiva fa ciò che farebbe qualsiasi altro blocco mutex: impedisce a thread diversi di acquisire lo stesso blocco allo stesso tempo.

Sintassi:

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

Esempio:

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

Ora il codice sopra è perfettamente thread-safe. Ora più thread possono modificare il valore.

Quanto sopra è solo un oscuro esempio ...


3
Non dovrebbe essere @synchronized (oldValue)?
Joel

O anche @synchronized(val, oldValue) { ... }?
Valentin Shergin

Non sono sicuro di aver mai visto uno schema che fosse "perfettamente thread-safe". Per lo meno devi sapere cosa stai facendo e non solo copiare ciecamente codice da qualche parte.
Hot Licks

Ma suppongo che il codice di cui sopra sia "perfettamente thread-safe" dopo tutto, poiché non fa assolutamente nulla.
Hot Licks



-2

@synchronizedè il thread safemeccanismo. Il pezzo di codice scritto all'interno di questa funzione diventa la parte di critical sectioncui può essere eseguito un solo thread alla volta.

@synchronizeapplica il blocco in modo implicito mentre lo NSLockapplica in modo esplicito.

Assicura solo la sicurezza del thread, non lo garantisce. Quello che voglio dire è che assumi un autista esperto per la tua auto, ma non garantisce che l'auto non incontrerà un incidente. Tuttavia la probabilità rimane la minima.


2
Questo è assolutamente sbagliato. dispatch_once NON fa la stessa cosa di @syncrhonized, può essere un sostituto SOLO sotto l'allocazione di un singleton.
jugutier
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.