Pergunta

Eu sou um programador Java e sei algumas coisas sobre enfiar int Java.

Em Java eu ??posso bloquear um método usando palavra-chave sincronizado:

private int a;
private int b;
private int c;
private synchronized void changeVars()
{
  a = 4;
  b = 2;
  c = a+b;
}

Eu procurei no MSDN e viu que existem alguns brinquedos em c # para jogar com threads. Tais como Monitor.Enter, monitor.Exit, bloqueio ou um um mutex avançada.

Mas o que eu preciso é sincronizar um método. O que é o equivalente a isso em c #?

Agradecemos antecipadamente.

Foi útil?

Solução

Algo como isso mayhaps:

using System.Runtime.CompilerServices;

...

private int a;
private int b;
private int c;

[MethodImpl(MethodImplOptions.Synchronized)]
private void changeVars()
{
  a = 4;
  b = 2;
  c = a+b;
}

Outras dicas

Não há equivalente direto em C #, mas você pode fazer a mesma coisa com isto:

private readonly object changeVarsLockObject = new object();

private void changeVars()
{
  lock(changeVarsLockObject)
  {
    a = 4;
    b = 2;
    c = a+b;
  }
}

Apenas para ser claro - declarando um método sincronizado em Java exige que o chamador mantém o monitor no objeto que o método foi chamado (que é o objeto Class para métodos estáticos)

Assim dizendo que você pode "travar um método" é enganosa como você não totalmente bloquear esse método (o mesmo método pode ainda ser chamado em objetos diferentes exemplo), e você bloquear mais do que isso método (nenhum outro pedaço de código que requer monitor do objeto alvo, incluindo outros métodos sincronizados ou adquire explícitas de que, podem ser executados ao mesmo tempo).

Sincronização é difícil , e, idealmente, você precisa saber mais do que "algumas coisas" sobre isso, se você quer evitar impasses e problemas de visibilidade que quase nunca aparecem durante os testes, ou conduzam a depuração . Tomar um possivelmente incompleta compreensão de sincronização em um idioma, e tentar levá-lo para outro idioma com diferentes primitivos e provavelmente um modelo de memória diferente é uma receita para o desastre.

Assim, enquanto esta não é a resposta one-liner você estava procurando, eu vou afirmar que qualquer resposta one-liner está fadado ao fracasso sem o conhecimento de todo o ecossistema para apoiá-la. Assim, você deve ler um bom livro / tutorial a sincronização em C #, em vez de tentar traduzir o seu Java experiência palavra-chave por palavra-chave.

O equivalente directa de que está a utilizar de bloqueio (este):

private void ChangeVars()
{
    lock (this) {
        a = 4;
        b = 2;
        c = a+b;
    }
}

ou mesmo usando o MethodImplAttribute como descrito por R. Bemrose, o que equivale à mesma coisa:

[MethodImpl(MethodImplOptions.Synchronized)]
private void ChangeVars()
{
    a = 4;
    b = 2;
    c = a+b;
}

... no entanto, não é recomendado o uso de um objeto publicamente visível para o bloqueio, já que alguém pode decidir usá-lo como um objeto de bloqueio, bem, então uma tradução melhor seria:

private object monitor = new object();
private void ChangeVars()
{
    lock (monitor) {
        a = 4;
        b = 2;
        c = a+b;
    }
}

A solução preferida é envolver o corpo do método em um comunicado lock.

internal class Foo
{
   private Object lockObject = new Object();

   private void ChangeVars()
   {
      lock (this.lockObject)
      {
         // Manipulate the state.
      }
   }
}

Você pode usar sincronização declarativa, também, mas este tem o inconveniente óbvio que você tem que derivar de ContextBoundObject e todos os métodos decorados com o Synchronization share atributo o mesmo objeto de bloqueio limitar a granularidade do bloqueio.

internal class Foo : ContextBoundObject
{
   [Synchronization]
   private void ChangeVars()
   {
      // Manipulate the state.
   }
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top