Pregunta

Soy un programador de Java y sé algunas cosas sobre threading int Java.

En Java puedo bloquear un método usando una palabra clave sincronizada:

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

Busqué en msdn y vi que hay algunos juguetes en c # para jugar con hilos. Como monitor.Enter, monitor.Exit, lock o un avanzado mutex.

Pero lo que necesito es sincronizar un método. ¿Cuál es el equivalente en C #?

Gracias de antemano.

¿Fue útil?

Solución

Tal vez algo como esto:

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

Otros consejos

No hay un equivalente directo en C #, pero puede hacer lo mismo con esto:

private readonly object changeVarsLockObject = new object();

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

Para ser claros: declarar un método sincronizado en Java requiere que la persona que llama mantenga el monitor en el objeto en el que se llamó al método (que es el objeto Class para métodos estáticos).

Entonces, decir que puedes '' bloquear un método '' es engañoso ya que no bloquea completamente ese método (el mismo método aún se puede invocar en diferentes objetos de instancia), y bloquea más que ese método (ningún otro bit de código que requiera el objeto de destino monitor, incluidos otros métodos sincronizados o adquisiciones explícitas, se puede ejecutar al mismo tiempo).

La sincronización es difícil , e idealmente necesita saber más que "algunas cosas". al respecto si desea evitar puntos muertos y problemas de visibilidad que casi nunca aparecen durante las pruebas o que conducen a la depuración. Tomar una comprensión posiblemente incompleta de la sincronización en un idioma y tratar de llevarlo a otro idioma con primitivas diferentes y probablemente un modelo de memoria diferente es una receta para el desastre.

Entonces, si bien esta no es la respuesta de una línea que estaba buscando, voy a afirmar que cualquier respuesta de una sola línea está condenada al fracaso sin el conocimiento de todo el ecosistema para respaldarla. Por lo tanto, debe leer un buen libro / tutorial sobre la sincronización en C #, en lugar de intentar traducir la palabra clave de su experiencia Java por palabra clave.

El equivalente directo de eso es usar lock (this):

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

o de hecho usando el MethodImplAttribute como lo describe R. Bemrose, que equivale a lo mismo:

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

... sin embargo, no se recomienda usar un objeto públicamente visible para bloquear, ya que otra persona podría decidir usarlo también como un objeto de bloqueo, por lo que una mejor traducción sería:

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

La solución preferida es envolver el cuerpo del método en una instrucción lock .

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

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

También puede usar la sincronización declarativa, pero esto tiene el inconveniente obvio que debe derivar de ContextBoundObject y todos los métodos decorados con Sincronización atributo comparte el mismo objeto de bloqueo que limita la granularidad de bloqueo.

internal class Foo : ContextBoundObject
{
   [Synchronization]
   private void ChangeVars()
   {
      // Manipulate the state.
   }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top