¿Qué hace @synchronized () como método singleton en el objetivo C?

87

Acabo de crear un método singleton y me gustaría saber qué hace la función @synchronized(), ya que la uso con frecuencia, pero no sé el significado.

max_
fuente

Respuestas:

119

Declara una sección crítica alrededor del bloque de código. En código multiproceso, @synchronizedgarantiza que solo un subproceso pueda ejecutar ese código en el bloque en un momento dado.

Si no sabe lo que hace, entonces su aplicación probablemente no sea multiproceso y probablemente no necesite usarla (especialmente si el singleton en sí no es seguro para subprocesos).


Editar: agregando más información que no estaba en la respuesta original de 2011.

La @synchronizeddirectiva evita que varios subprocesos entren en cualquier región de código que esté protegida por una @synchronizeddirectiva que haga referencia al mismo objeto . El objeto que se pasa a la @synchronizeddirectiva es el objeto que se utiliza como "bloqueo". Dos subprocesos pueden estar en la misma región de código protegida si se usa un objeto diferente como bloqueo, y también puede proteger dos regiones de código completamente diferentes usando el mismo objeto que el bloqueo.

Además, si pasa nilcomo el objeto de bloqueo, no se tomará ningún bloqueo.

John Calsbeek
fuente
14
Un par de puntos importantes: 1) Si usa un puntero nulo en @synchronizedél, no hace nada, queda desprotegido. 2) @synchronizedes lento .
Hot Licks
Esta respuesta es engañosa y no debería ser la respuesta aceptada. Aunque lo que dice a veces sería correcto (siempre que el token pasado a synhronized sea ​​el mismo objeto en todos los hilos), es engañosamente incompleto.sincronizado evita que cualquier número de secciones de código asociadas se ejecuten al mismo tiempo, no solo "ese código en el bloque". El parámetro para sincronizar efectivamente determina qué secciones de código (o "bloques" como los llama la respuesta) están protegidas del acceso concurrente.
Arda
@Arda Tienes toda la razón. Agregué un poco más de información y un enlace a documentación de Apple sobre @synchronized.
John Calsbeek
@JohnCalsbeek, la respuesta se ve mucho mejor ahora. Pulgares arriba de mi parte.
Arda
@HotLicks es interesante señalar esto, pero hubiera sido aún mejor decir brevemente cuáles podrían ser las alternativas (¿enlaces?)
itMaxence
43

De la documentación de Apple aquí y aquí :

La directiva @synchronized es una forma conveniente de crear bloqueos mutex sobre la marcha en el código Objective-C. La directiva @synchronized hace lo que haría cualquier otro bloqueo mutex: evita que diferentes subprocesos adquieran el mismo bloqueo al mismo tiempo.

La documentación proporciona una gran cantidad de información sobre este tema. Vale la pena tomarse el tiempo para leerlo, especialmente dado que lo ha estado usando sin saber lo que hace.

csano
fuente
26

La @synchronizeddirectiva es una forma conveniente de crear bloqueos mutex sobre la marcha en el código Objective-C .

los @synchronized directiva hace lo que haría cualquier otro bloqueo mutex: evita que diferentes subprocesos adquieran el mismo bloqueo al mismo tiempo.

Sintaxis:

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

Ejemplo:

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

Ahora el código anterior es perfectamente seguro para subprocesos ... Ahora varios subprocesos pueden cambiar el valor.

Lo anterior es solo un oscuro ejemplo ...

Durai Amuthan.H
fuente
3
¿No debería ser @synchronized (oldValue)?
Joel
¿O incluso @synchronized(val, oldValue) { ... }?
Valentin Shergin
No estoy seguro de haber visto ningún esquema que fuera "perfectamente seguro para subprocesos". Como mínimo, necesita saber lo que está haciendo y no simplemente copiar ciegamente el código de algún lugar.
Hot Licks
Pero supongo que el código anterior es "perfectamente seguro para subprocesos" después de todo, ya que no hace absolutamente nada.
Hot Licks
-2

@synchronizedes thread safemecanismo. El fragmento de código escrito dentro de esta función se convierte en parte de la critical sectionque solo se puede ejecutar un hilo a la vez.

@synchronizeaplica el bloqueo implícitamente mientras que lo NSLockaplica explícitamente.

Solo asegura la seguridad del hilo, no garantiza eso. Lo que quiero decir es que contrata a un conductor experto para su automóvil, pero eso no garantiza que el automóvil no sufra un accidente. Sin embargo, la probabilidad sigue siendo la más mínima.


fuente
2
Esto está absolutamente mal. dispatch_once NO hace lo mismo que @syncrhonized, puede ser un sustituto SOLO bajo la asignación de un singleton.
jugutier