O código a seguir resultará em um impasse usando o C # no .NET?
class MyClass
{
private object lockObj = new object();
public void Foo()
{
lock(lockObj)
{
Bar();
}
}
public void Bar()
{
lock(lockObj)
{
// Do something
}
}
}
Respostas:
Não, desde que você esteja travando no mesmo objeto. O código recursivo já possui efetivamente o bloqueio e, portanto, pode continuar sem impedimentos.
lock(object) {...}
é uma abreviação para usar a classe Monitor . Como Marc aponta ,Monitor
permite a reentrada , portanto, repetidas tentativas de bloquear um objeto no qual o thread atual já possui um bloqueio funcionarão perfeitamente.Se você começar a travar objetos diferentes , é aí que você deve ter cuidado. Preste especial atenção a:
Se você quebrar uma dessas regras, estará praticamente garantido que haverá problemas de conflito em algum momento .
Aqui está uma boa página da Web que descreve a sincronização de threads no .NET: http://dotnetdebug.net/2005/07/20/monitor-class-avoiding-deadlocks/
Além disso, prenda o menor número possível de objetos ao mesmo tempo. Considere aplicar bloqueios de granulação grossa sempre que possível. A idéia é que, se você pode escrever seu código de forma que exista um gráfico de objetos e adquirir bloqueios na raiz desse gráfico de objetos, faça-o. Isso significa que você tem um bloqueio nesse objeto raiz e, portanto, não precisa se preocupar muito com a sequência na qual você adquire / libera bloqueios.
(Mais uma observação, seu exemplo não é tecnicamente recursivo. Para ser recursivo,
Bar()
teria que se chamar, normalmente como parte de uma iteração.)fonte
Bem,
Monitor
permite a reentrada, para que você não possa entrar em conflito ... então não: não deve funcionarfonte
Se um encadeamento já estiver segurando uma trava, ele não se bloqueará. A estrutura .Net garante isso. Você só precisa garantir que dois encadeamentos não tentem obter os mesmos dois bloqueios fora de sequência por quaisquer caminhos de código.
O mesmo encadeamento pode adquirir o mesmo bloqueio várias vezes, mas você deve liberar o bloqueio o mesmo número de vezes que o adquiriu. Obviamente, desde que você esteja usando a palavra-chave "lock" para fazer isso, isso acontece automaticamente.
fonte
Não, esse código não terá bloqueios. Se você realmente deseja criar um impasse mais simples, precisará de pelo menos 2 recursos. Considere o cenário do cão e do osso. 1. Um cão tem controle total sobre 1 osso, então qualquer outro cão tem que esperar. 2. São necessários no mínimo 2 cães com 2 ossos para criar um impasse quando prendem seus ossos respectivamente e procuram outros ossos também.
.. e assim por diante n cães e ossos e causam impasses mais sofisticados.
fonte