Saturday, December 28, 2024
Google search engine
HomeLanguagesJavaBanking Transaction System using Java

Banking Transaction System using Java

In order to understand one must have a strong grasp over  Java OOPs, Java Multithreading & Java Interrupted-Exception. If not go through them as the title in itself is a sheer implementation of multithreading.

Approaches:

  1. Rookie approach
  2. Multithreading approach
  3. Synchronization invoking in multithreading approach

In order to understand, let us consider an illustration in order to implement the approach.

Illustration:

We will discuss the architecture of the banking transaction system using java. Throughout this editorial, I will hold your hands and take you through the entire transaction procedure and make it Easy-Pease for you to understand so that you can even explain it to your friends. For the sake of simplicity, we have considered a joint bank account having 5 owners(Arnab, Monodwip, Mukta, Rinkel, and Shubham) and the initial balance is a hundred dollars ($100). The transactions of the account are listed as follows:

Name Balance($) Withdrawal($) Deposit($) Comment                                              Final Balance($)
Arnab 100 20  

Arnab has withdrawn 20                         

Balance after withdrawal: 80      

80
Monodwip 80 40  

Monodwip withdrawn 40

Balance after withdrawal: 40   

40
Mukta 40   35

Mukta deposited 35

Balance after deposit: 75

75
Rinkel 75 80  

Rinkel you can not withdraw 80

your balance is: 75   

75
Shubham 75 40  

Shubham withdrawn 40  

Balance after withdrawal: 35      

35

Approach 1: Rookie approach

We have declared the “withdraw” and “deposit” method inside the class “Bank” and accessed them from the driver class “GFG” by creating an object “obj” of Bank class.

Example

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);
    }
}


Output:

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

There are certain cons associated with the Rookie approach as depicted below: 

No 2 people can make transactions at the same time, one needs to wait till the former finishes its transaction. If the number of people is large then we need to wait and wait until our turn comes. To demonstrate this problem, we made the thread sleep for 3 seconds during each transaction in the video provided below. In real life, it would take much time making this approach incapable of implementation in real transaction projects.

Method 2: Multithreading Approach

How multithreading can help?

Multithreading allows different threads to work at the same time without having any dependency on one-another. So large group of threads can perform an operation at the same time. 

Example

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();
    }
}


Output:

Now there are certain problems with the multithreading approach as listed below:

When multiple threads try to do a particular operation at the same time then there exists a possibility of bad output, this is because all the threads are updating the same resource at a time. In the above output, we got balance in negative figures due to the same reason.

How to handle those cases where multiple people try to access the same operation at a time?

If multiple threads access a single resource at a time then there exists a possibility of bad output. This unwanted phenomenon is defined as data racing.

Suppose we have $100 in our joint bank account. To trick the banker, both of us can request $100 simultaneously at a time. The system will create an object, assign 2 threads and pass them to the withdrawal method. At the end of the process, both of us will have $100!

To handle this problem engineers came up with the synchronization concept.

Method 3: Incorporating synchronization with multithreading

Synchronization provides a lock to the object and declares a sensitive area (withdraw & deposit methods). An object can have multiple threads but the sensitive area can only be accessed by 1 thread at a time. The thread scheduler chooses the order of execution of the threads. As it is a random process the output is different for each interpretation.

Why should we use static synchronization?

Say we have 5 thread classes with 1 object each. Each object have multiple threads. Now the sensitive area will be accessed by 5 threads at a time! To handle this problem engineers came up with the idea of static synchronization. We provide a lock to the class. The class will select 1 object at a time. The object in turn will choose 1 thread and pass it through the sensitive area.

Does synchronized multithreaded execution slower than the normal execution without multithreading?

No. The amount of time one task spends waiting for another is considered as overhead. In synchronized multithreading, this overhead time can be used to do other productive work until the waiting thread gets the key from the thread scheduler to get inside the synchronized area. Thus the overhead would be minimal in the case of synchronized multithreaded execution, so we can expect it to be faster.

Example

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();
    }
}


Output(Compiled & Interpreted):

Output(Interpreted): Shubham & Monodwip failed to withdraw money

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

Output(Interpreted): Rinkel failed to withdraw money.

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

Output(Interpreted): Monodwip failed to withdraw money.

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

Note: The thread scheduler chooses the order of execution of the threads. As it is a random process the output is different for each interpretation.

RELATED ARTICLES

Most Popular

Recent Comments