O que @synchronized () faz como um método singleton no objetivo C?

87

Acabei de criar um método singleton e gostaria de saber o que a função @synchronized()faz, já que a uso com frequência, mas não sei o significado.

max_
fonte

Respostas:

119

Ele declara uma seção crítica em torno do bloco de código. No código multithread, @synchronizedgarante que apenas um thread possa executar aquele código no bloco a qualquer momento.

Se você não está ciente do que ele faz, então seu aplicativo provavelmente não é multithread e você provavelmente não precisa usá-lo (especialmente se o singleton em si não é seguro para thread).


Edit: Adicionando mais algumas informações que não estavam na resposta original de 2011.

A @synchronizeddiretiva impede que vários threads entrem em qualquer região do código protegida por uma @synchronizeddiretiva que se refira ao mesmo objeto . O objeto passado para a @synchronizeddiretiva é o objeto usado como "bloqueio". Duas threads podem estar na mesma região protegida do código se um objeto diferente for usado como bloqueio, e você também pode proteger duas regiões completamente diferentes do código usando o mesmo objeto como bloqueio.

Além disso, se você passar nilcomo o objeto de bloqueio, nenhum bloqueio será levado.

John Calsbeek
fonte
14
Alguns pontos importantes: 1) Se você usar um ponteiro nulo, @synchronizedele não fará nada - você ficará desprotegido. 2) @synchronizedé lento .
Hot Licks
Essa resposta é enganosa e não deve ser aceita. Embora o que ele diz às vezes seja correto (desde que o token passado para sincronizado seja o mesmo objeto em todos os threads), ele é enganosamente incompleto. synchronized impede que qualquer número de seções de código associadas seja executado ao mesmo tempo, não apenas "aquele código no bloco". O parâmetro para synchronized efetivamente determina quais seções de código (ou "blocos" como a resposta os chama) são protegidas de acesso simultâneo.
Arda de
@Arda Você está totalmente certo. Eu adicionei um pouco mais de informações e um link para alguma documentação da Apple sobre @synchronized.
John Calsbeek,
@JohnCalsbeek, a resposta parece muito melhor agora. Perfeito para mim.
Arda
@HotLicks interessante apontar isso, mas teria sido ainda melhor dizer brevemente quais poderiam ser as alternativas (links?)
itMaxence
43

Da documentação da Apple aqui e aqui :

A diretiva @synchronized é uma maneira conveniente de criar bloqueios mutex dinamicamente no código Objective-C. A diretiva @synchronized faz o que qualquer outro bloqueio mutex faria - evita que diferentes threads adquiram o mesmo bloqueio ao mesmo tempo.

A documentação fornece muitas informações sobre este assunto. Vale a pena reservar um tempo para lê-lo, principalmente porque você o tem usado sem saber o que está fazendo.

csano
fonte
26

A @synchronizeddiretiva é uma maneira conveniente de criar bloqueios mutex dinamicamente no código Objective-C .

A @synchronizeddiretiva faz o que qualquer outro bloqueio mutex faria - impede que diferentes threads adquiram o mesmo bloqueio ao mesmo tempo.

Sintaxe:

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

Exemplo:

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

Agora o código acima é perfeitamente thread-safe ... Agora, vários threads podem alterar o valor.

O acima é apenas um exemplo obscuro ...

Durai Amuthan.H
fonte
3
Não deveria ser @synchronized (oldValue)?
Joel
Ou mesmo @synchronized(val, oldValue) { ... }?
Valentin Shergin
Não tenho certeza se já vi algum esquema que fosse "perfeitamente thread-safe". No mínimo, você precisa saber o que está fazendo e não apenas copiar cegamente o código de algum lugar.
Hot Licks de
Mas suponho que o código acima seja "perfeitamente thread-safe", já que não faz absolutamente nada.
Hot Licks de
6

O bloco @synchronized controla automaticamente o bloqueio e desbloqueio para você . @synchronize você tem um bloqueio implícito associado ao objeto que está usando para sincronizar. Aqui está uma discussão muito informativa sobre este tópico, por favor siga. Como @synchronized bloqueia / desbloqueia em Objective-C?

abdus.me
fonte
-2

@synchronizedé o thread safemecanismo. O trecho de código escrito dentro dessa função torna-se parte da critical sectionqual apenas um thread pode ser executado por vez.

@synchronizeaplica o bloqueio implicitamente enquanto o NSLockaplica explicitamente.

Apenas garante a segurança do fio, não garante isso. O que quero dizer é que você contrata um motorista especializado para o seu carro, mas isso não garante que o carro não sofrerá um acidente. No entanto, a probabilidade permanece a menor.


fonte
2
Isso está absolutamente errado. dispatch_once NÃO faz o mesmo que @syncrhonized, ele pode ser um substituto SOMENTE sob a alocação de um singleton.
jugutier de