2011-06-11 22 views
75

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.¿Qué hace @synchronized()?

+1

Posible duplicado de http://stackoverflow.com/q/6234344/277952? – NSGod

Respuesta

103

Declara critical section alrededor del bloque de código. En el código multiproceso, @synchronized garantiza que solo un hilo puede ejecutar ese código en el bloque en cualquier momento dado.

Si no tiene conocimiento de lo que hace, entonces su aplicación probablemente no es multihilo, y probablemente no necesite usarla (especialmente si el singleton no es seguro para subprocesos).


Editar: Adición de mayor información que no estaba en la respuesta original a partir de 2011.

La Directiva @synchronizedprevents multiple threads from entering any region of code that is protected by a @synchronized directive referring to the same object. El objeto que se pasa a la directiva @synchronized es el objeto que se utiliza como "bloqueo". Dos hilos pueden estar en la misma región protegida de código si se usa un objeto diferente como el bloqueo, y también puede proteger dos regiones de código completamente diferentes usando el mismo objeto que el candado.

Además, si pasa nil como objeto de bloqueo, no se realizará ningún bloqueo.

+12

Un par de puntos importantes: 1) Si usa un puntero nulo en '@ synchronized', no hace nada; quedará desprotegido. 2) '@ sincronizado' es * lento *. –

+0

Esta respuesta es engañosa y no debe 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 * impide que se ejecute al mismo tiempo cualquier cantidad de secciones de código asociadas, no solo "ese código en el bloque". El parámetro * * synchronized * determina de manera efectiva qué secciones de código (o "bloques", como la llama la respuesta) están protegidas contra el acceso concurrente. – Arda

+0

@Arda Tienes toda la razón. He agregado un poco más de información y un enlace a cierta documentación de Apple sobre '@ synchronized'. –

42

A partir de la documentación de Apple here y here:

La directiva @synchronized es una manera conveniente para crear bloqueos mutex sobre la marcha en el código Objective-C. La Directiva @synchronized hace lo que cualquier otra bloqueo mutex haría-previene hilos diferentes de la adquisición de la misma 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 has estado usando sin saber lo que está haciendo.

6

@synchronized block se encarga automáticamente de bloquear y desbloquear. @synchronize tiene un bloqueo implícito asociado con el objeto que está utilizando para sincronizar. Aquí es muy informativo discusión sobre este tema, por favor siga How does @synchronized lock/unlock in Objective-C?

25

La directiva @synchronized es una manera conveniente de crear bloqueos mutex sobre la marcha en código Objective-C.

La directiva @synchronized hace lo mismo que cualquier otro bloqueo mutex: evita que diferentes hilos 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 thread safe..Now múltiples hilos puede cambiar el valor.

Lo anterior es sólo un ejemplo oscura ...

+3

¿No debería ser @synchronized (oldValue)? – Joel

+0

O incluso '@synchronized (val, oldValue) {...}'? –

+0

No estoy seguro de haber visto algún esquema que sea "perfectamente seguro para subprocesos". Por lo menos, necesitas saber lo que estás haciendo y no solo copiar ciegamente código de algún lado. –

0

@synchronized es thread safe mecanismo. La pieza de código escrita dentro de esta función se convierte en la parte de critical section, a la que solo se puede ejecutar un hilo a la vez.

@synchronize aplica el bloqueo implícitamente mientras que NSLock lo aplica explícitamente.

Solo garantiza la seguridad del hilo, no garantiza eso. Lo que quiero decir es que contratas un conductor experto para tu auto, pero no garantiza que el auto no sufra un accidente. Sin embargo, la probabilidad sigue siendo la más mínima.

+1

Esto es absolutamente incorrecto. dispatch_once NO hace lo mismo que @syncrhonized, puede ser un sustituto SÓLO bajo la asignación de un singleton. – jugutier