fork download
  1. using System;
  2. using System.Threading;
  3.  
  4. namespace Recetas.Multithreading.Cap02.R0201
  5. {
  6. public sealed class Contadores
  7. {
  8. public static void Main()
  9. {
  10. Console.Title = "Demostración de Contadores Sincronizados y No Sincronizados";
  11. Console.WriteLine ();
  12.  
  13. Console.WriteLine ("--- Resultado Inconsiste de Contador ---");
  14.  
  15. // Creación de instancia de `ContadorBase`:
  16. ContadorEstandar contador = new ContadorEstandar();
  17.  
  18. // Creación de threads:
  19. Thread t1 = new Thread (() => ProbarContadores(contador));
  20. Thread t2 = new Thread (() => ProbarContadores(contador));
  21. Thread t3 = new Thread (() => ProbarContadores(contador));
  22.  
  23. // Inicio ejecución threads:
  24. t1.Start();
  25. t2.Start();
  26. t3.Start();
  27.  
  28. // Espera a que todos terminen:
  29. t1.Join();
  30. t2.Join();
  31. t3.Join();
  32.  
  33. Console.WriteLine ("\tCuenta total: {0}", contador.Contador.ToString());
  34.  
  35. Console.WriteLine ("\n--- Resultado Consiste de Contador ---");
  36.  
  37. // Creación de contador sincrónico:
  38. ContadorSincronizado contadorSinc = new ContadorSincronizado();
  39.  
  40. // Creación de nuevos threads:
  41. t1 = new Thread (() => ProbarContadores(contadorSinc));
  42. t2 = new Thread (() => ProbarContadores(contadorSinc));
  43. t3 = new Thread (() => ProbarContadores(contadorSinc));
  44.  
  45. // Inicio ejecución threads:
  46. t1.Start();
  47. t2.Start();
  48. t3.Start();
  49.  
  50. // Espera a que todos terminen:
  51. t1.Join();
  52. t2.Join();
  53. t3.Join();
  54.  
  55. Console.WriteLine ("\tCuenta total: {0}\n", contadorSinc.Contador.ToString());
  56.  
  57. Console.WriteLine ("Presione `Enter` para terminar.");
  58. }
  59.  
  60. // Método que invoca 100 mil veces los métodos `Incrementar`
  61. // y `Decrementar`:
  62. private static void ProbarContadores (ContadorBase contador)
  63. {
  64. for (int i = 0; i < 100000; ++i)
  65. {
  66. contador.Incrementar();
  67. contador.Decrementar();
  68. }
  69. }
  70. }
  71.  
  72. public abstract class ContadorBase
  73. {
  74. public abstract void Incrementar();
  75. public abstract void Decrementar();
  76. }
  77.  
  78. // Esta clase no cuenta con un mecanismo de
  79. // sincronización de las operaciones de incremento
  80. // y decremento; los resultados pueden ser inconsistentes:
  81. public class ContadorEstandar : ContadorBase
  82. {
  83. private int contador;
  84.  
  85. public int Contador
  86. {
  87. get
  88. {
  89. return contador;
  90. }
  91. }
  92.  
  93. public override void Incrementar()
  94. {
  95. ++contador;
  96. }
  97.  
  98. public override void Decrementar()
  99. {
  100. --contador;
  101. }
  102. }
  103.  
  104. // Clase que sincroniza los incrementos y decrementos
  105. // de forma sincrónica usando la clase Interlocked:
  106. public class ContadorSincronizado : ContadorBase
  107. {
  108. private int contador;
  109.  
  110. public int Contador
  111. {
  112. get
  113. {
  114. return contador;
  115. }
  116. }
  117.  
  118. public override void Incrementar()
  119. {
  120. Interlocked.Increment (ref contador);
  121. }
  122.  
  123. public override void Decrementar()
  124. {
  125. Interlocked.Decrement (ref contador);
  126. }
  127. }
  128. }
Success #stdin #stdout 0.04s 36976KB
stdin
Standard input is empty
stdout
--- Resultado Inconsiste de Contador ---
	Cuenta total: 0

--- Resultado Consiste de Contador ---
	Cuenta total: 0

Presione `Enter` para terminar.