using System; using System.Threading; namespace Recetas.Multithreading.R0202 { public sealed class BloqueoMutuo { public static void Main() { Console.Title = "=== Demostración Bloqueo Mutuo ==="; Console.WriteLine (); // Instancias de `Object` para bloqueo de regiones críticas: object bloqueo1 = new object(); object bloqueo2 = new object(); // Creación de un objeto `Thread` para iniciar el método // `Bloquear`: new Thread (() => Bloquear(bloqueo1, bloqueo2)).Start(); // Intento casi simultáneo de región crítica con el objeto // `bloqueo2`: lock (bloqueo2) { // Espera durante un segundo: Thread.Sleep (1000); Console.WriteLine ("La invocación del método `Monitor.TryEnter` evita el bloqueo " + "de la aplicación, en caso de no liberarse el recurso solicitado se esperan " + "5 segundos" ); if (Monitor.TryEnter (bloqueo1, TimeSpan.FromSeconds (5))) { Console.WriteLine ("Acceso satisfactorio a recurso protegido."); } else { Console.WriteLine ("El tiempo de espera se superó."); } } // Creación de un nuevo objeto `Thread` para invocar nuevamente // el método `Bloquear`: new Thread (() => Bloquear (bloqueo1, bloqueo2)).Start(); Console.WriteLine ("\n----------------------------------"); lock (bloqueo2) { Console.WriteLine ("Aquí ocurre un bloqueo mutuo (deadlock)."); Thread.Sleep (1000); lock (bloqueo1) { Console.WriteLine ("Acceso satisfactorio a recurso protegido."); } } } private static void Bloquear(object bloqueo1, object bloqueo2) { lock (bloqueo1) { Thread.Sleep (1000); lock (bloqueo2); } } } }