8
votes

Qu'est-ce que signifie exactement verrouillant sur un objet?

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


0 commentaires

5 Réponses :


8
votes

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; } } }


0 commentaires

8
votes

L'objet lui-même n'est pas verrouillé. Pensez à chaque objet comme ayant un lock associé (ou moniteur ). 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 moniteur.exit.exit (ce qui se passe à la fin d'un verrouillage instruction) ou en appelant moniteur.wait . Un appel de fil moniteur.enter pour acquérir la serrure bloquera jusqu'à ce qu'il puisse acquérir la serrure.

L'objet lui-même n'est pas "protégé" sur tout - les serrures sont consultatifs, fondamentalement.

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é Syncroot sur les collections .NET 1.1).


0 commentaires

1
votes

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.


0 commentaires

1
votes

Lorsque vous utilisez verrouillage (personnage) {... 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) {} Régions Verrouillage sur le même objet, un seul thread peut entrer l'une de ces régions.

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 Ce est mauvais pour la même raison.

Créer un nouvel objet privé et verrouille à ce sujet.


0 commentaires

0
votes
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");
                                }
                        }
                 }

1 commentaires

Ceci est un programme simple sur la synchronisation