Este artigo é um artigo espelhado de tradução automática, por favor clique aqui para ir para o artigo original.

Vista: 20563|Resposta: 0

[Fonte] A palavra-chave bloqueio C# marca um bloco de instruções como área crítica ao obter um mutex para um determinado objeto, executando a instrução, mas...

[Copiar link]
Publicado em 31/12/2015 17:51:01 | | |
A palavra-chave lock marca um bloco de instruções como uma zona crítica ao pegar um mutex para um determinado objeto, executar a instrução e então liberar o bloqueio.

A instrução lock basicamente usa Monitor.Enter e Monitor.Exit, ou seja, Monitor.Enter(this) é executado quando lock(this) é executado, e Monitor.Exit(this) é executado no final da colteada curly. Qual é o seu significado? Para qualquer objeto, a primeira parte da memória é o endereço de todos os métodos, e a segunda parte é um índice. Ele aponta para um SyncBlock na área de cache SyncBlock do CLR. O que isso significa? Ou seja, quando você executa o Monitor.Enter(Object), se o valor do índice do objeto for negativo, selecione um SyncBlock do Cache do SyncBlock e coloque seu endereço no índice do objeto. Isso completa o bloqueio marcado por objeto, e as outras threads querem realizar novamente a operação Monitor.Enter(objeto), o que obterá um índice com um objeto positivo, e então esperar. Até que o índice se torne negativo, ou seja, a thread usa Monitor.Exit(object) para tornar o índice negativo.

O que você precisa prestar atenção ao usar a fechadura:
1.lock não pode travar valor nulo Um objeto pode apontar para nulo, mas nulo não precisa ser liberado. (Veja também: Entendendo o Nulo Completo)
2.lock não pode travar o tipo de string, embora também seja um tipo de referência. Porque o tipo de string é "pairado" pelo CLR
Isso significa que há apenas uma instância de uma string em todo o programa, e esse mesmo objeto representa esse texto em todas as threads de todos os domínios de aplicação em execução. Portanto, desde que um lock seja colocado em uma string com o mesmo conteúdo em qualquer lugar do processo de aplicação, todas as instâncias dessa string na aplicação serão travadas. Portanto, é melhor trancar membros privados ou protegidos que não serão persistidos.
3.locklock O objeto é a fronteira de memória de um bloco de programa
4. O tipo de valor não pode ser bloqueado, porque o "objeto é liberado" em vermelho no texto anterior, e o tipo de valor não é um tipo de referência
5.lock evita travar tipos públicos ou objetos que não são controlados pelo programa.
Por exemplo, se a instância for acessível publicamente, o lock(this) pode ser problemático porque código não controlado também pode travar o objeto. Isso pode levar a deadlocks, onde duas ou mais threads aguardam para liberar o mesmo objeto. Bloquear tipos de dados públicos (em oposição a objetos) também pode causar problemas pelo mesmo motivo.
Ao usar lock(this), o valor da variável membro da classe pode ser alterado pelo método que não está na zona crítica

Cenário de aplicação: É frequentemente usado para evitar exceções incertas no valor de variáveis públicas causadas por operações multithreaded, garantindo a segurança das operações

  1. // statements_lock2.cs
  2. using System;
  3. using System.Threading;

  4. class Account
  5. {
  6.     private Object thisLock = new Object();
  7.     int balance;

  8.     Random r = new Random();

  9.     public Account(int initial)
  10.     {
  11.         balance = initial;
  12.     }

  13.     int Withdraw(int amount)
  14.     {

  15.         // This condition will never be true unless the lock statement
  16.         // is commented out:
  17.         if (balance < 0)
  18.         {
  19.             throw new Exception("Negative Balance");
  20.         }

  21.         // Comment out the next line to see the effect of leaving out
  22.         // the lock keyword:
  23.         lock(thisLock)
  24.         {
  25.             if (balance >= amount)
  26.             {
  27.                 Console.WriteLine("Balance before Withdrawal :  " + balance);
  28.                 Console.WriteLine("Amount to Withdraw        : -" + amount);
  29.                 balance = balance - amount;
  30.                 Console.WriteLine("Balance after Withdrawal  :  " + balance);
  31.                 return amount;
  32.             }
  33.             else
  34.             {
  35.                 return 0; // transaction rejected
  36.             }
  37.         }
  38.     }

  39.     public void DoTransactions()
  40.     {
  41.         for (int i = 0; i < 100; i++)
  42.         {
  43.             Withdraw(r.Next(1, 100));
  44.         }
  45.     }
  46. }

  47. class Test
  48. {
  49.     static void Main()
  50.     {
  51.         Thread[] threads = new Thread[10];
  52.         Account acc = new Account(1000);
  53.         for (int i = 0; i < 10; i++)
  54.         {
  55.             Thread t = new Thread(new ThreadStart(acc.DoTransactions));
  56.             threads[i] = t;
  57.         }
  58.         for (int i = 0; i < 10; i++)
  59.         {
  60.             threads[i].Start();
  61.         }
  62.     }
  63. }
Copiar código








Anterior:Win8 inicia o serviço SQL Server 2012
Próximo:[Speed] Scanner de portas abertas de segmento IP para velocidade de varredura rápida!!
Disclaimer:
Todo software, material de programação ou artigos publicados pela Code Farmer Network são apenas para fins de aprendizado e pesquisa; O conteúdo acima não deve ser usado para fins comerciais ou ilegais, caso contrário, os usuários terão todas as consequências. As informações deste site vêm da Internet, e disputas de direitos autorais não têm nada a ver com este site. Você deve deletar completamente o conteúdo acima do seu computador em até 24 horas após o download. Se você gosta do programa, por favor, apoie um software genuíno, compre o registro e obtenha serviços genuínos melhores. Se houver qualquer infração, por favor, entre em contato conosco por e-mail.

Mail To:help@itsvse.com