c# - threads - synchronization thread
¿Versión C#de la palabra clave sincronizada de java? (5)
¿C # tiene su propia versión de la palabra clave "sincronizada" de java?
No. En C #, lock
explícitamente lock
recursos en los que desea trabajar de forma síncrona en subprocesos asíncronos. lock
abre un bloque; no funciona a nivel de método.
Sin embargo, el mecanismo subyacente es similar ya que el lock
funciona invocando Monitor.Enter
(y posteriormente Monitor.Exit
) en el tiempo de ejecución. Java funciona de la misma manera, de acuerdo con la documentación de Sun.
¿C # tiene su propia versión de la palabra clave "sincronizada" de java?
Es decir, en java se puede especificar para una función, un objeto o un bloque de código, de esta manera
public synchronized void doImportantStuff() {
// dangerous code goes here.
}
o
public void doImportantStuff() {
// trivial stuff
synchronized(someLock) {
// dangerous code goes here.
}
}
Primero: la mayoría de las clases nunca tendrán que ser seguras para subprocesos Use YAGNI : solo aplique seguridad para subprocesos cuando sepa que realmente lo va a usar (y lo pruebe).
Para las cosas a nivel de método, hay [MethodImpl]
:
[MethodImpl(MethodImplOptions.Synchronized)]
public void SomeMethod() {/* code */}
Esto también se puede utilizar en los accesores (propiedades y eventos):
private int i;
public int SomeProperty
{
[MethodImpl(MethodImplOptions.Synchronized)]
get { return i; }
[MethodImpl(MethodImplOptions.Synchronized)]
set { i = value; }
}
Tenga en cuenta que los eventos tipo campo se sincronizan de forma predeterminada, mientras que las propiedades implementadas automáticamente no lo están :
public int SomeProperty {get;set;} // not synchronized
public event EventHandler SomeEvent; // synchronized
Personalmente, no me gusta la implementación de MethodImpl
ya que bloquea this
o typeof(Foo)
, lo que va en contra de las mejores prácticas. La opción preferida es usar tus propios candados:
private readonly object syncLock = new object();
public void SomeMethod() {
lock(syncLock) { /* code */ }
}
Tenga en cuenta que para eventos similares a campos, la implementación de bloqueo depende del compilador; en los compiladores más antiguos de Microsoft, es un lock(this)
/ lock(Type)
; sin embargo, en los compiladores más recientes usa actualizaciones Interlocked
, por lo que es seguro para subprocesos sin las partes desagradables.
Esto permite un uso más granular y permite el uso de Monitor.Wait
/ Monitor.Pulse
etc. para comunicarse entre los subprocesos.
Una entrada de blog relacionada (más tarde revisada ).
Puede utilizar la instrucción de lock
lugar. Creo que esto solo puede reemplazar la segunda versión. Además, recuerde que tanto la synchronized
como el lock
deben operar en un objeto.
Tome nota, con las rutas completas, la línea: [MethodImpl(MethodImplOptions.Synchronized)]
debería verse como
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.Synchronized)]
static object Lock = new object();
lock (Lock)
{
// do stuff
}