Sistema de transacciones bancarias usando Java

Para comprender, uno debe tener un conocimiento sólido de   Java OOP , Java Multithreading y Java Interrupted-Exception . Si no, revíselos, ya que el título en sí mismo es una pura implementación de subprocesos múltiples.

Enfoques:

  1. enfoque de novato
  2. Enfoque de subprocesos múltiples
  3. Invocación de sincronización en el enfoque de subprocesos múltiples

Para entender, consideremos una ilustración para implementar el enfoque.

Ilustración:

Discutiremos la arquitectura del sistema de transacciones bancarias utilizando java. A lo largo de este editorial, lo tomaré de la mano y lo guiaré a través de todo el procedimiento de transacción y lo haré fácil de entender para que incluso pueda explicárselo a sus amigos. En aras de la simplicidad, hemos considerado una cuenta bancaria conjunta con 5 propietarios (Arnab, Monodwip, Mukta, Rinkel y Shubham) y el saldo inicial es de cien dólares ($100). Las transacciones de la cuenta se enumeran a continuación:

Nombre Saldo ($) Retiro ($) Depósito ($) Comentario                                              Saldo final ($)
Arnab 100 20  

Arnab ha retirado 20                         

Saldo después del retiro: 80      

80
Monodwip 80 40  

Monodwip retirado 40

Saldo después del retiro: 40   

40
Muktá 40   35

Mukta depositó 35

Saldo después del depósito: 75

75
Rinkel 75 80  

Rinkel no puedes retirar 80

tu saldo es: 75   

75
Shubham 75 40  

Shubham retirado 40  

Saldo después del retiro: 35      

35

Enfoque 1: enfoque de novato

Hemos declarado el método «retirar» y «depositar» dentro de la clase «Banco» y acceder a ellos desde la clase de controlador «GFG» creando un objeto «obj» de la clase Banco.

Ejemplo

Java

// Java Program to illustrate Rookie Approach
// In Banking transaction system
 
// Class  1
// Bank class
// Defining the banking transaction
class Bank {
 
    // Initial balance $100
    int total = 100;
 
    // Money withdrawal method. Withdraw only if
    // total money greater than or equal to the money
    // requested for withdrawal
 
    // Method
    // To withdraw money
    void withdrawn(String name, int withdrawal)
    {
        if (total >= withdrawal) {
            System.out.println(name + " withdrawn "
                               + withdrawal);
 
            total = total - withdrawal;
            System.out.println("Balance after withdrawal: "
                               + total);
            // Making the thread sleep for 1 second after
            // each withdrawal
 
            // Try block to check for exceptions
            try {
 
                // Making thread t osleep for 1 second
                Thread.sleep(1000);
            }
 
            // Catch block to handle the exceptions
            catch (InterruptedException e) {
 
                // Display the exception along with line
                // number
                // using printStacktrace() method
                e.printStackTrace();
            }
        }
 
        // If the money requested for withdrawal is greater
        // than the balance then deny transaction*/
        else {
 
            // Print statements
            System.out.println(name
                               + " you can not withdraw "
                               + withdrawal);
 
            System.out.println("your balance is: " + total);
 
            // Making the thread sleep for 1 second after
            // each transaction failure
 
            // Try block to check for exceptions
            try {
                Thread.sleep(1000);
            }
 
            catch (InterruptedException e) {
 
                e.printStackTrace();
            }
        }
    }
 
    // Method - to deposit money
    // Accept money whenever deposited
    void deposit(String name, int deposit)
    {
        System.out.println(name + " deposited " + deposit);
        total = total + deposit;
        System.out.println("Balance after deposit: "
                           + total);
        // Making the thread sleep for 1 second after
        // each deposit
        try {
            Thread.sleep(1000);
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
// Class 2
// main class
class GFG {
 
    // Main driver method
    public static void main(String[] args)
    {
        // Declaring an object of Bank class and calling the
        // withdarwn and deposit methods with suitable
        // parameters
 
        // Creating object of class 1 inside main()
        Bank obj = new Bank();
 
        // Custom input - Transactions
        obj.withdrawn("Arnab", 20);
        obj.withdrawn("Monodwip", 40);
        obj.deposit("Mukta", 35);
        obj.withdrawn("Rinkel", 80);
        obj.withdrawn("Shubham", 40);
    }
}

Producción:

C:\Users\USER\Desktop\LearnCoding\MultiThreading>javac GFG.java
C:\Users\USER\Desktop\LearnCoding\MultiThreading>java GFG
Arnab withdrawn 20
Balance after withdrawal: 80

//After 1 Second
Monodwip withdrawn 40
Balance after withdrawal: 40

//After 1 Second
Mukta deposited 35
Balance after deposit: 75

//After 1 Second
Rinkel you can not withdraw 80
your balance is: 75

//After 1 Second
Shubham withdrawn 40
Balance after withdrawal: 35

Hay ciertas desventajas asociadas con el enfoque Rookie como se muestra a continuación: 

Dos personas no pueden realizar transacciones al mismo tiempo, una debe esperar hasta que la primera finalice su transacción. Si el número de personas es grande, debemos esperar y esperar hasta que llegue nuestro turno. Para demostrar este problema, hicimos que el subproceso se suspendiera durante 3 segundos durante cada transacción en el video que se proporciona a continuación. En la vida real, llevaría mucho tiempo hacer que este enfoque no se pueda implementar en proyectos de transacciones reales.

Método 2: enfoque de subprocesos múltiples

¿Cómo pueden ayudar los subprocesos múltiples?

Los subprocesos múltiples permiten que diferentes subprocesos funcionen al mismo tiempo sin tener ninguna dependencia entre sí. Un gran grupo de subprocesos puede realizar una operación al mismo tiempo. 

Ejemplo

Java

// Java Program to illustrate Multithreading Approach
// In Banking transaction system
 
// Class 1
// Helper class
class Bank {
 
    // Initial custom balance
    int total = 100;
 
    // Money withdrawal method. Withdraw only if total money
    // greater than or equal to the money requested for
    // withdrawal
    void withdrawn(String name, int withdrawal)
    {
 
        if (total >= withdrawal) {
            System.out.println(name + " withdrawn "
                               + withdrawal);
            total = total - withdrawal;
 
            System.out.println(total);
 
            //  Making the thread sleep for 1 second after
            //   each withdrawal
 
            // Try block to check for exceptions
            try {
 
                // Making thread to sleep for 1 second
                Thread.sleep(1000);
            }
 
            catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
 
        // Else if the money requested for withdrawal is
        // greater than the balance then deny transaction
        else {
 
            System.out.println(name
                               + " you can not withdraw "
                               + withdrawal);
            System.out.println("your balance is: " + total);
 
            // Making the thread sleep for 1 second after
            // each transaction failure
 
            try {
                Thread.sleep(1000);
            }
            catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
 
    // Method - To deposit money
    // Accepting money whenever deposited
    void deposit(String name, int deposit)
    {
        System.out.println(name + " deposited " + deposit);
        total = total + deposit;
        System.out.println("Balance after deposit: "
                           + total);
        // Making the thread sleep for 1 second after
        // each deposit
 
        try {
            Thread.sleep(1000);
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
 
// Method - Withdraw method
// Called from ThreadWithdrawal class
// using the object of Bank class passed
// from the main() method
class ThreadWithdrawal extends Thread {
 
    Bank object;
    String name;
    int dollar;
 
    // Constructor of this method
    ThreadWithdrawal(Bank ob, String name, int money)
    {
        this.object = ob;
        this.name = name;
        this.dollar = money;
    }
 
    // run() method for thread
    public void run() { object.withdrawn(name, dollar); }
}
// Deposit method is called from ThreadDeposit class
// using the object of Bank class passed
// from the main method
class ThreadDeposit extends Thread {
 
    Bank object;
    String name;
    int dollar;
    ThreadDeposit(Bank ob, String name, int money)
    {
        // This keyword refers t ocurrent instance itself
        this.object = ob;
        this.name = name;
        this.dollar = money;
    }
 
    public void run() { object.deposit(name, dollar); }
}
 
// Class 2
// Main class
class GFG {
 
    // Main driver method
    public static void main(String[] args)
    {
        // Declaring an object of Bank class and passing the
        // object along with other parameters to the
        // ThreadWithdrawal and ThreadDeposit class. This
        // will be required to call withdrawn and deposit
        // methods from those class
 
        // Creating an object of class1
        Bank obj = new Bank();
 
        ThreadWithdrawal t1
            = new ThreadWithdrawal(obj, "Arnab", 20);
        ThreadWithdrawal t2
            = new ThreadWithdrawal(obj, "Monodwip", 40);
        ThreadDeposit t3
            = new ThreadDeposit(obj, "Mukta", 35);
        ThreadWithdrawal t4
            = new ThreadWithdrawal(obj, "Rinkel", 80);
        ThreadWithdrawal t5
            = new ThreadWithdrawal(obj, "Shubham", 40);
 
        // When a program calls the start() method, a new
        // thread is created and then the run() method is
        // executed.
 
        // Starting threads created above
        t1.start();
        t2.start();
        t3.start();
        t4.start();
        t5.start();
    }
}

Producción:

Ahora bien, hay ciertos problemas con el enfoque de subprocesos múltiples, como se indica a continuación:

Cuando varios subprocesos intentan realizar una operación en particular al mismo tiempo, existe la posibilidad de un resultado incorrecto, esto se debe a que todos los subprocesos están actualizando el mismo recurso a la vez. En la salida anterior, obtuvimos saldo en cifras negativas por la misma razón.

¿Cómo manejar esos casos en los que varias personas intentan acceder a la misma operación a la vez?

Si varios subprocesos acceden a un solo recurso a la vez, existe la posibilidad de una mala salida. Este fenómeno no deseado se define como carrera de datos.

Supongamos que tenemos $100 en nuestra cuenta bancaria conjunta. Para engañar al banquero, ambos podemos solicitar $100 simultáneamente a la vez. El sistema creará un objeto, asignará 2 hilos y los pasará al método de retiro. ¡Al final del proceso, ambos tendremos $100!

Para manejar este problema, los ingenieros idearon el concepto de sincronización.

Método 3: Incorporación de sincronización con subprocesos múltiples

La sincronización proporciona un bloqueo al objeto y declara un área sensible (métodos de retiro y depósito). Un objeto puede tener varios subprocesos, pero solo se puede acceder al área sensible mediante 1 subproceso a la vez. El planificador de subprocesos elige el orden de ejecución de los subprocesos. Como es un proceso aleatorio, la salida es diferente para cada interpretación.

¿Por qué deberíamos usar la sincronización estática?

Digamos que tenemos 5 clases de subprocesos con 1 objeto cada una. Cada objeto tiene múltiples hilos. ¡Ahora se accederá al área sensible por 5 subprocesos a la vez! Para manejar este problema, a los ingenieros se les ocurrió la idea de la sincronización estática. Proporcionamos un bloqueo a la clase. La clase seleccionará 1 objeto a la vez. El objeto a su vez elegirá 1 hilo y lo pasará por el área sensible.

¿La ejecución sincronizada de subprocesos múltiples es más lenta que la ejecución normal sin subprocesos múltiples?

No. La cantidad de tiempo que una tarea pasa esperando a otra se considera sobrecarga. En subprocesos múltiples sincronizados, este tiempo de sobrecarga se puede usar para realizar otro trabajo productivo hasta que el subproceso en espera obtenga la clave del programador de subprocesos para ingresar al área sincronizada. Por lo tanto, la sobrecarga sería mínima en el caso de la ejecución sincronizada de subprocesos múltiples, por lo que podemos esperar que sea más rápida.

Ejemplo

Java

// Java Program to illustrate Multithreading Approach
// With Synchronization In Banking transaction system
 
// Class 1
// Helper class
class Bank {
 
    // Initial balance $100
    static int total = 100;
 
    // Money withdrawal method. Withdraw only if total money
    // greater than or equal to the money requested for
    // withdrawal
    static synchronized void withdrawn(String name,
                                       int withdrawal)
    {
        if (total >= withdrawal) {
            System.out.println(name + " withdrawn "
                               + withdrawal);
            total = total - withdrawal;
            System.out.println("Balance after withdrawal: "
                               + total);
            /* Making the thread sleep for 1 second after
                 each withdrawal.*/
            try {
                Thread.sleep(1000);
            }
            catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
 
        // If the money requested for withdrawal is greater
        // than the balance then deny transaction
        else {
            System.out.println(name
                               + " you can not withdraw "
                               + withdrawal);
            System.out.println("your balance is: " + total);
 
            // Making the thread sleep for 1 second after
            //   each transaction failure
 
            // Try block to check for exceptions
            try {
 
                // Making thread to sleep for 1 second
                Thread.sleep(1000);
            }
 
            // Catch bloc kto handle exceptions
            catch (InterruptedException e) {
 
                // Display the line number where exception
                // occurred
                // Using printStackTrace() method
                e.printStackTrace();
            }
        }
    }
 
    // Method - Deposit method
    // Accepting money whenever deposited
    static synchronized void deposit(String name,
                                     int deposit)
    {
        System.out.println(name + " deposited " + deposit);
        total = total + deposit;
        System.out.println("Balance after deposit: "
                           + total);
 
        // Making the thread sleep for 1 second
        // after each deposit
 
        // Try block to check for exceptions
        try {
 
            // Making thread to sleep for 1 second
            Thread.sleep(1000);
        }
 
        // Catch block to handle InterruptedException
        // exception
        catch (InterruptedException e) {
 
            e.printStackTrace();
        }
    }
}
 
// Method - Withdraw
// It is called from ThreadWithdrawal class using
// the object of Bank class passed from the main method
class ThreadWithdrawal extends Thread {
 
    // Attributes of this class
    Bank object;
    String name;
    int dollar;
 
    // Constructor of this class
    ThreadWithdrawal(Bank ob, String name, int money)
    {
        // This keyword refers to parent class
        this.object = ob;
        this.name = name;
        this.dollar = money;
    }
 
    // run() method for the thread
    public void run() { object.withdrawn(name, dollar); }
}
 
// Deposit method is called from ThreadDeposit class using
// the object of Bank class passed from the main method*/
 
// Class 2
// Helper class extending Thread class
class ThreadDeposit extends Thread {
 
    Bank object;
    String name;
    int dollar;
 
    ThreadDeposit(Bank ob, String name, int money)
    {
        this.object = ob;
        this.name = name;
        this.dollar = money;
    }
 
    public void run() { object.deposit(name, dollar); }
}
 
// Class 3
// Main class
class GFG {
 
    // Main driver method
    public static void main(String[] args)
    {
        // Declaring an object of Bank class and passing the
        // object along with other parameters to the
        // ThreadWithdrawal and ThreadDeposit class. This
        // will be required to call withdrawn and deposit
        // methods from those class
 
        // Creating object of above class inside main()
        Bank obj = new Bank();
 
        // Creating threads
        ThreadWithdrawal t1
            = new ThreadWithdrawal(obj, "Arnab", 20);
        ThreadWithdrawal t2
            = new ThreadWithdrawal(obj, "Monodwip", 40);
        ThreadDeposit t3
            = new ThreadDeposit(obj, "Mukta", 35);
        ThreadWithdrawal t4
            = new ThreadWithdrawal(obj, "Rinkel", 80);
        ThreadWithdrawal t5
            = new ThreadWithdrawal(obj, "Shubham", 40);
 
        // When a program calls the start() method, a new
        // thread is created and then the run() method is
        // executed
        t1.start();
        t2.start();
        t3.start();
        t4.start();
        t5.start();
    }
}

Salida (Compilado e interpretado):

Salida (interpretada): Shubham y Monodwip no pudieron retirar dinero

C:\Users\USER\Desktop\Network Java>java  GFG

Arnab withdrawn 20
Balance after withdrawal: 80
Rinkel withdrawn 80
Balance after withdrawal: 0
Shubham you can not withdraw 40
your balance is: 0
Mukta deposited 35
Balance after deposit: 35
Monodwip you can not withdraw 40
your balance is: 35

Salida (interpretada): Rinkel no pudo retirar dinero.

C:\Users\USER\Desktop\Network Java>java  GFG

Arnab withdrawn 20
Balance after withdrawal: 80
Shubham withdrawn 40
Balance after withdrawal: 40
Monodwip withdrawn 40
Balance after withdrawal: 0
Mukta deposited 35
Balance after deposit: 35
Rinkel you can not withdraw 80
your balance is: 35

Salida (interpretada): Monodwip no pudo retirar dinero.

C:\Users\USER\Desktop\Network Java>java  GFG

Arnab withdrawn 20
Balance after withdrawal: 80
Rinkel withdrawn 80
Balance after withdrawal: 0
Shubham you can not withdraw 40
your balance is: 0
Monodwip you can not withdraw 40
your balance is: 0
Mukta deposited 35
Balance after deposit: 35

Nota: El planificador de subprocesos elige el orden de ejecución de los subprocesos. Como es un proceso aleatorio, la salida es diferente para cada interpretación.

Publicación traducida automáticamente

Artículo escrito por dattabikash505 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *