fork download
  1. using System;
  2. using System.Threading;
  3.  
  4. namespace Recetas.Multithreading.Cap04.R0109
  5. {
  6. // Representa una cuanta Bancaria:
  7. public class Cuenta
  8. {
  9. // Instancia Object para el bloque concurrente
  10. // a un sección crítica:
  11. private Object bloqueo = new Object();
  12. private int saldo;
  13.  
  14. // Objeto Random para simular la cantidad de dinero
  15. // a retirar:
  16. Random aleatorio = new Random();
  17.  
  18. public Cuenta(int saldoInicial)
  19. {
  20. saldo = saldoInicial;
  21. }
  22.  
  23. // Retiro de dinero:
  24. public int Retirar(int cantidad)
  25. {
  26. // Comprueba que la cuenta tenga fondos para el retiro:
  27. if (saldo < 0)
  28. {
  29. throw new Exception ("Saldo Negativo.");
  30. }
  31.  
  32. // Sección crítica. Sólo se permite una transacción
  33. // de retiro de forma simultánea:
  34. lock (bloqueo)
  35. {
  36. if (saldo >= cantidad)
  37. {
  38. Console.WriteLine ("Saldo antes del retiro: {0}", saldo.ToString());
  39. Console.WriteLine ("Cantidad a retirar: -{0}", cantidad.ToString());
  40. saldo -= cantidad;
  41. Console.WriteLine ("Saldo después del retiro: {0}", saldo.ToString());
  42. return cantidad;
  43. }
  44. else
  45. {
  46. return 0;
  47. }
  48. }
  49. }
  50.  
  51. // Simula la ejecución de 100 transacciones:
  52. public void RealizarTransaccion()
  53. {
  54. for (int i = 1; i <= 100; ++i)
  55. {
  56. // Realiza retiros entre 1 y 100 unidades monetarias:
  57. Retirar(aleatorio.Next(1, 101));
  58. }
  59. }
  60. }
  61.  
  62. public sealed class Banco
  63. {
  64. public static void Main()
  65. {
  66. Console.Title = "Uso de lock para transacciones bancarias";
  67. Console.WriteLine ();
  68.  
  69. // Crea un arreglo de 10 threads:
  70. Thread[] threads = new Thread[10];
  71.  
  72. // Una cuenta para arealizar transacciones,
  73. // y un saldo inicial de 1000 unidades monetarias:
  74. Cuenta c = new Cuenta(1000);
  75.  
  76. // Crea las 10 instancias de Thread:
  77. for (int i = 0; i < 10; ++i)
  78. {
  79. Thread t = new Thread(new ThreadStart(c.RealizarTransaccion));
  80. threads[i] = t;
  81. }
  82.  
  83. // Inicia los threads para ejecución simultánea:
  84. for (int i = 0; i < 10; ++i)
  85. {
  86. threads[i].Start();
  87. }
  88.  
  89. Console.WriteLine ();
  90. }
  91. }
  92. }
Success #stdin #stdout 0.04s 40136KB
stdin
Standard input is empty
stdout
Saldo antes del retiro: 1000
Cantidad a retirar: -61
Saldo después del retiro: 939
Saldo antes del retiro: 939
Cantidad a retirar: -2
Saldo después del retiro: 937
Saldo antes del retiro: 937
Cantidad a retirar: -38
Saldo después del retiro: 899
Saldo antes del retiro: 899
Cantidad a retirar: -79
Saldo después del retiro: 820
Saldo antes del retiro: 820
Cantidad a retirar: -43
Saldo después del retiro: 777
Saldo antes del retiro: 777
Cantidad a retirar: -65
Saldo después del retiro: 712
Saldo antes del retiro: 712
Cantidad a retirar: -18
Saldo después del retiro: 694
Saldo antes del retiro: 694
Cantidad a retirar: -85
Saldo después del retiro: 609
Saldo antes del retiro: 609
Cantidad a retirar: -47
Saldo después del retiro: 562
Saldo antes del retiro: 562
Cantidad a retirar: -85
Saldo después del retiro: 477
Saldo antes del retiro: 477
Cantidad a retirar: -39
Saldo después del retiro: 438
Saldo antes del retiro: 438
Cantidad a retirar: -77
Saldo después del retiro: 361
Saldo antes del retiro: 361
Cantidad a retirar: -28
Saldo después del retiro: 333
Saldo antes del retiro: 333
Cantidad a retirar: -11
Saldo después del retiro: 322
Saldo antes del retiro: 322
Cantidad a retirar: -24
Saldo después del retiro: 298
Saldo antes del retiro: 298
Cantidad a retirar: -15
Saldo después del retiro: 283
Saldo antes del retiro: 283
Cantidad a retirar: -96
Saldo después del retiro: 187
Saldo antes del retiro: 187
Cantidad a retirar: -35
Saldo después del retiro: 152
Saldo antes del retiro: 152
Cantidad a retirar: -97
Saldo después del retiro: 55
Saldo antes del retiro: 55
Cantidad a retirar: -5
Saldo después del retiro: 50
Saldo antes del retiro: 50
Cantidad a retirar: -20
Saldo después del retiro: 30
Saldo antes del retiro: 30
Cantidad a retirar: -10
Saldo después del retiro: 20
Saldo antes del retiro: 20
Cantidad a retirar: -6
Saldo después del retiro: 14
Saldo antes del retiro: 14
Cantidad a retirar: -9
Saldo después del retiro: 5
Saldo antes del retiro: 5
Cantidad a retirar: -2
Saldo después del retiro: 3
Saldo antes del retiro: 3
Cantidad a retirar: -1
Saldo después del retiro: 2
Saldo antes del retiro: 2
Cantidad a retirar: -2
Saldo después del retiro: 0