Banking Transaction System using Java - GeeksforGeeks

29 Apr, 2022
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:
Rookie approachMultithreading approachSynchronization invoking in multithreading approach
Rookie approach
Multithreading approach
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:
Arnab has withdrawn 20                         
Balance after withdrawal: 80      
Monodwip withdrawn 40
Balance after withdrawal: 40   
Mukta deposited 35
Balance after deposit: 75
Rinkel you can not withdraw 80
your balance is: 75   
Shubham withdrawn 40  
Balance after withdrawal: 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 transactionclass 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 classclass 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 classclass 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() methodclass 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 methodclass 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 classclass 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.
YouTubeGeeksforGeeks502K subscribersSynchronization | GeeksforGeeksWatch laterShareCopy linkInfoShoppingTap to unmuteIf playback doesn't begin shortly, try restarting your device.You're signed outVideos you watch may be added to the TV's watch history and influence TV recommendations. To avoid this, cancel and sign in to YouTube on your computer.CancelConfirmMore videosMore videosSwitch cameraShareInclude playlistAn error occurred while retrieving sharing information. Please try again later.Watch on0:000:000:00 / 18:31•Live•<div class="player-unavailable"><h1 class="message">An error occurred.</h1><div class="submessage"><a href="https://www.youtube.com/watch?v=IIgHG_YHXPE" target="_blank">Try watching this video on www.youtube.com</a>, or enable JavaScript if it is disabled in your browser.</div></div>
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 classclass 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) {                 // Displa ythe 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 methodclass 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 classclass 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 classclass 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.
dattabikash505
gulshankumarar231
anikakapoor
sweetyty
Blogathon-2021
Blogathon
Java
Project
Java
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Python NOT EQUAL operator
Difference Between Local Storage, Session Storage And Cookies
Changing CSS styling with React onClick() Event
How to Connect Python with SQL Database?
How to parse JSON Data into React Table Component ?
For-each loop in Java
Reverse a string in Java
Arrays.sort() in Java with examples
Initialize an ArrayList in Java
Object Oriented Programming (OOPs) Concept in Java