Search code examples
javamultithreadingjava-threads

Multi Threading banking simulation


At this moment I'm playing around with Multi Threading in java and I'm not sure how this works.. I feel like I understood this in a simple example I've seen on the internet but somehow I can't understand how this works in a banking simulation app I found and modified from the internet.

Here's what I have:

Person class:

package threadsproject;

public class Person {

    private String name;

    public Person(String name){
        this.name = name;
    }

    public String getName(){
        return name;
    }

    public void setName(String name){
        this.name = name;
    }
}

Account class:

package threadsproject;

public class Account {

    public static int balance;
    public static Account acc;
    private static Person p;

    public static int getBal(){
        return balance;
    }

    public void setBal(int bal){
        Account.balance = bal;
    }

    public static Account getAcc(Person p){
        if(acc == null){
            acc = new Account();
        }
        Account.p = p;
        return acc;

    }

    public synchronized void deposit(int val){
        try{

            if(val > 0){
                System.out.println("Person "+p.getName()+" is making a deposit.");
                try{
                    Thread.sleep(500);
                }catch(Exception e){}
                balance = balance + val;
                System.out.println("Person "+p.getName()+" completed the deposit.");
            }else{
                System.out.println("Can't deposit.");
            }
            System.out.println("Person "+p.getName()+" deposited "+val);

        }catch(Exception e){}
    }

    public synchronized void withdraw(int val){
        try{

            if(balance >= val){
                System.out.println("Person "+p.getName()+" is making a withdraw.");
                try{
                    Thread.sleep(500);
                }catch(Exception e){}
                balance = balance - val;
                System.out.println("Person "+p.getName()+" completed the withdraw.");
            }else{
                System.out.println("Can't withdraw.");
            }
            System.out.println("Person "+p.getName()+" withdrew "+val);

        }catch(Exception e){}
    }

}

Thread Class:

package threadsproject;

import java.util.Scanner;

public class BankThread extends Thread implements Runnable{

    private Person p;

    public BankThread(Person p){
        this.p = p;
    }

    public void run(){
        for (int i = 0; i < 3; i++) {
            try {
                Account acc = Account.getAcc(p);
                Scanner s = new Scanner(System.in);
                System.out.println("Enter deposit ammount:");
                int dep = s.nextInt();
                acc.deposit(dep);
                try {
                    Thread.sleep(500);
                } catch (InterruptedException ex) { }

                System.out.println("Enter withdrawal ammount:");
                int with = s.nextInt();
                if(with > Account.getBal()){
                    System.out.println("You don't have enough funds.");
                }else{
                    acc.withdraw(with);
                }
                System.out.println("Final balance: "+Account.getBal());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        // TODO Auto-generated method stub

        Person p1 = new Person("Person1");
        Person p2 = new Person("Person2");
        Person p3 = new Person("Person3");
        BankThread bt1 = new BankThread(p1);
        bt1.start();
        bt1.join();
        BankThread bt2 = new BankThread(p2);
        bt2.start();
        bt2.join();
        BankThread bt3 = new BankThread(p3);
        bt3.start();
        bt3.join();
    }

}

As I mentioned, it's an example I found and modified. This works but not correctly I think. In the threads class, the for loop goes and executes the code for each thread 3 times. And another problem I have is that the account balance remains the same for each thread. So, if I have 100 final balance for my first thread, the second one starts the same, with 100 balance and not from 0. If I have different objects, it should start from 0 right?

Here's a screenshot.

enter image description here


Solution

  • Your described scenario mirrors the usage of static member fields in your Account class. The keyword static means that the fields are not object-bounded anymore, because they are class-bounded. So every instance of your Account object will have the same static field over any instance of it.

    To fix it you have to remove the static fields

     public static int balance;
     public static Account acc;
     private static Person p;