Imagine una instancia de una clase con una variable global en ella. Imagine que dos hilos llaman a un método en ese objeto exactamente al mismo tiempo, y ese método actualiza la variable global dentro.
La probabilidad es que el valor de la variable se corrompa. Diferentes lenguajes y compiladores/intérpretes tratarán esto de diferentes maneras (o no lo harán en absoluto ...) pero el punto es que obtienes resultados "no deseados" e "impredecibles".
Imagine que el método obtiene un "bloqueo" en la variable antes de intentar leer o escribir en ella. El primer hilo para llamar al método obtendrá un "bloqueo" en la variable, el segundo hilo para llamar al método tendrá que esperar hasta que el primer hilo libere el bloqueo. Mientras todavía tenga una condición de carrera (es decir, el segundo subproceso podría sobrescribir el valor del primero), al menos tiene resultados predecibles porque no hay dos subprocesos (que no se conocen entre sí) que pueden modificar el valor al mismo tiempo.
Utiliza la instrucción lock
para obtener ese bloqueo en la variable. Normalmente desea definir una variable objeto separado y el uso que para el objeto de bloqueo:
public class MyThreadSafeClass
{
private readonly object lockObject = new object();
private string mySharedString;
public void ThreadSafeMethod(string newValue)
{
lock (lockObject)
{
// Once one thread has got inside this lock statement, any others will have to wait outside for their turn...
mySharedString = newValue;
}
}
}
Un tipo se considera "thread-safe" si se aplica el principio de que hay corrupción ocurrirá si los datos compartidos se accede por múltiples hilos al mismo tiempo.
Tenga cuidado con la diferencia entre "inmutable" y "seguro para subprocesos". Thread-safe dice que ha codificado el escenario y no se dañará si dos subprocesos acceden al estado compartido al mismo tiempo, mientras que la inmutabilidad simplemente dice que devuelve un objeto nuevo en lugar de modificarlo. Los objetos inmutables son seguros para subprocesos, pero no todos los objetos seguros para subprocesos son inmutables. código seguro
Entonces, si un tipo es seguro para subprocesos, implementa el bloqueo internamente y no debería volver a implementarlo. ¿Está bien? Gracias Neil. –
Sí, si reutiliza el tipo de otra persona (por ejemplo, desde una biblioteca de terceros) y se anuncia como "seguro para subprocesos", no debería necesitar escribir el 'candado (...) {... } 'declaraciones sobre los usos del mismo. Sin embargo, si está configurando una variable de ese tipo y la variable misma puede ser modificada por diferentes hilos, debe bloquearla. –