Allez j'utilise des serrures dans mon application, je ne comprends pas ce qui verrouille exactement sur un type de référence particulier. Je pensais que cela arrête simplement le fil jusqu'à la fin du contenu de {}. Mais j'ai lu que verrouiller (ceci) est mauvais, si son public - pourquoi? L'article l'a expliqué mais je ne comprends pas que je ne sais pas ce qui est arrivé à l'objet lui-même enfermé. Par exemple, si j'utilise le verrouillage (ceci) et d'un autre thread appeler sa méthode? Je pensais que seul le code sous la serrure est protégé ou je ne pourrai pas accéder à l'objet verrouillé du tout? Merci p>
5 Réponses :
Chaque objet sur le tas géré peut être utilisé comme objet de verrouillage, ce qui est un moyen de synchroniser l'accès entre les threads.
Je pensais qu'il arrête simplement le fil jusqu'à la fin du contenu de {}. p> blockQuote>
Eh bien, un
LOCK CODE> Il arrête Autre threads forts> d'acquérir la serrure jusqu'à ce que le verrou soit libéré, ce qui est le plus souvent à la fin d'un
verrouillage code> instruction (mais cela pourrait aussi être un
moniteur.Wait code>). p>
Le verrouillage
code> L'utilisation est dangereuse car le verrouillage est complexe et comprend exactement quels threads verrouillent quels objets (s) objet (s) à quel moment sont très importants pour éviter les blocages; Toutefois, si vous
verrouillage (ceci) code> vous ne contrôlez pas d'autres threads - ce qui pourrait aussi em> être (de manière inattendue) verrouillant le même objet. Il est beaucoup plus sûr d'utiliser un champ
privé code> pour le verrouillage. P>
à titre d'exemple, si vous avez (dans une liste synchronisée): p>
private readonly object syncLock = new object(); public int Count { get { lock(syncLock) { return innerList.Count; } } }
L'objet lui-même n'est pas verrouillé. Pensez à chaque objet comme ayant un em> lock em> associé (ou moniteur em>). Lorsqu'un thread a acquis la serrure, aucun autre thread ne peut l'acquérir sans le premier fil le relâchant, soit en appelant L'objet lui-même n'est pas "protégé" sur tout - les serrures sont consultatifs, fondamentalement. P>
La raison de ne pas verrouiller "Ceci" est que vous ne savez pas quel autre code a une référence à "Ceci". Obtenir un droit de verrouillage nécessite que vous sachiez dans quelles situations un thread sera ou ne possédera pas la serrure - et vous ne pouvez pas savoir que si le code en dehors de votre contrôle peut retirer la serrure. L'exception à cet égard est que si vous exposez une référence à des fins explicites du partage d'une serrure (comme la propriété moniteur.exit.exit code> (ce qui se passe à la fin d'un
verrouillage code> instruction) ou en appelant
moniteur.wait code>. Un appel de fil
moniteur.enter code> pour acquérir la serrure bloquera jusqu'à ce qu'il puisse acquérir la serrure. P>
Syncroot code> sur les collections .NET 1.1). P>
verrouillage d'un objet ne fait rien à l'objet lui-même - cela signifie simplement que tout autre fil essayant de verrouiller le même objet sera bloqué jusqu'à ce que le fil de verrouillage le libère. La raison pour laquelle verrouille (ceci) est fronçée sur le fait que d'autres codes en dehors de l'objet peuvent également verrouiller l'objet et interférer ainsi avec son fonctionnement normal. P>
Lorsque vous utilisez Le verrouillage est généralement un détail de mise en œuvre à garder privé. C'est une mauvaise idée de verrouiller un membre public car cela signifie que les clients de votre classe peuvent également se verrouiller sur ce même objet et peuvent entraîner des blocages ou un ralentissement inutile. Verrouillage sur Créer un nouvel objet privé et verrouille à ce sujet. P> verrouillage (personnage) {... Code ...} code> Cela signifie que lorsque le thread peut être à l'intérieur de la région verrouillée à la fois (en supposant toujours que vous verrouillez toujours sur le même objet! ). Un deuxième fil qui tente d'entrer dans la région bloquera et doit attendre que le premier fil le feuille. Si vous avez deux
verrouillage (ToNObject) {} code> Régions Verrouillage sur le même objet, un seul thread peut entrer l'une de ces régions. P>
Ce code> est mauvais pour la même raison. P>
using System; using System.Threading; class sycexp { public static void Main() { exp e=new exp(); Thread t1=new Thread(new ThreadStart(e.show)); Thread t2=new Thread(new ThreadStart(e.show)); t1.Name="First Thread"; t2.Name="Second Thread"; t1.Start(); t2.Start(); } } class exp { public object lockme=new object(); public void show() { lock(lockme) { Console.WriteLine("Start "+Thread.CurrentThread.Name.ToString()); Console.WriteLine("1"); Console.WriteLine("2"); Console.WriteLine("3"); Console.WriteLine("4"); Console.WriteLine("5"); Console.WriteLine(Thread.CurrentThread.Name.ToString()+" Stopped"); } } }
Ceci est un programme simple sur la synchronisation