Que fait @synchronized () en tant que méthode singleton dans l'objectif C?

87

Je viens de créer une méthode singleton, et j'aimerais savoir ce que fait la fonction @synchronized(), car je l'utilise fréquemment, mais je ne connais pas la signification.

max_
la source

Réponses:

119

Il déclare une section critique autour du bloc de code. Dans le code multithread, @synchronizedgarantit qu'un seul thread peut exécuter ce code dans le bloc à un moment donné.

Si vous ne savez pas ce qu'il fait, votre application n'est probablement pas multithread et vous n'avez probablement pas besoin de l'utiliser (surtout si le singleton lui-même n'est pas thread-safe).


Edit: Ajout d'informations supplémentaires qui ne figuraient pas dans la réponse d'origine de 2011.

La @synchronizeddirective empêche plusieurs threads d'entrer dans une région de code protégée par une @synchronizeddirective faisant référence au même objet . L'objet passé à la @synchronizeddirective est l'objet qui est utilisé comme "verrou". Deux threads peuvent être dans la même région protégée du code si un objet différent est utilisé comme verrou, et vous pouvez également protéger deux régions de code complètement différentes en utilisant le même objet que le verrou.

De plus, si vous passez nilcomme objet de verrouillage, aucun verrou ne sera pris du tout.

John Calsbeek
la source
14
Quelques points importants: 1) Si vous utilisez un pointeur nul, @synchronizedcela ne fait rien - vous n'êtes pas protégé. 2) @synchronizedest lent .
Hot Licks
Cette réponse est trompeuse et ne devrait pas être la réponse acceptée. Bien que ce qu'il dit soit parfois correct (tant que le jeton passé à synhronized est le même objet dans tous les threads), il est incomplet à tort . synchronized empêche tout nombre de sections de code associées de s'exécuter en même temps, pas seulement "ce code dans le bloc". Le paramètre à synchroniser détermine effectivement quelles sections de code (ou «blocs» comme la réponse les appelle) sont protégées contre l'accès simultané.
Arda
@Arda Vous avez tout à fait raison. J'ai ajouté un peu plus d'informations et un lien vers une documentation Apple sur @synchronized.
John Calsbeek
@JohnCalsbeek, la réponse semble bien meilleure maintenant. Bravo de moi.
Arda
@HotLicks intéressant de le souligner, mais il aurait été encore mieux de dire brièvement quelles pourraient être les alternatives (liens?)
itMaxence
43

De la documentation Apple ici et ici :

La directive @synchronized est un moyen pratique de créer des verrous mutex à la volée dans du code Objective-C. La directive @synchronized fait ce que ferait n'importe quel autre verrou mutex: elle empêche différents threads d'acquérir le même verrou en même temps.

La documentation fournit une mine d'informations sur ce sujet. Cela vaut la peine de prendre le temps de le lire, d'autant plus que vous l'utilisez sans savoir ce qu'il fait.

csano
la source
26

La @synchronizeddirective est un moyen pratique de créer des verrous mutex à la volée dans du code Objective-C .

La @synchronizeddirective fait ce que n'importe quel autre verrou mutex ferait: elle empêche différents threads d'acquérir le même verrou en même temps.

Syntaxe:

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

Exemple:

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

Maintenant, le code ci-dessus est parfaitement thread-safe..Maintenant, plusieurs threads peuvent changer la valeur.

Ce qui précède n'est qu'un exemple obscur ...

Durai Amuthan.H
la source
3
Ne devrait-il pas être @synchronized (oldValue)?
Joel
Ou même @synchronized(val, oldValue) { ... }?
Valentin Shergin
Je ne suis pas sûr d'avoir jamais vu de système "parfaitement thread-safe". À tout le moins, vous devez savoir ce que vous faites et pas seulement copier aveuglément du code quelque part.
Hot Licks
Mais je suppose que le code ci-dessus est "parfaitement thread-safe" après tout, car il ne fait absolument rien.
Hot Licks
6

Le bloc @synchronized gère automatiquement le verrouillage et le déverrouillage pour vous . @synchronize vous avez un verrou implicite associé à l'objet que vous utilisez pour synchroniser. Voici une discussion très informative sur ce sujet, veuillez suivre Comment @synchronized verrouille / déverrouille dans Objective-C?

abdus.me
la source
-2

@synchronizedest le thread safemécanisme. Le morceau de code écrit à l'intérieur de cette fonction devient la partie de critical section, sur laquelle un seul thread peut s'exécuter à la fois.

@synchronizeapplique le verrou implicitement alors NSLockqu'il l'applique explicitement.

Il assure seulement la sécurité du fil, pas le garantit. Ce que je veux dire, c'est que vous embauchez un chauffeur expert pour votre voiture, mais cela ne garantit pas que la voiture ne rencontrera pas d'accident. Cependant, la probabilité reste la moindre.


la source
2
C'est absolument faux. dispatch_once NE fait PAS la même chose que @syncrhonized, il peut être un substitut UNIQUEMENT sous l'allocation d'un singleton.
jugutier