title: Bank Account/User Application: Multi-threading and Synchronization
body: <p>for my current uni coursework, I'm meant to create a Java console application that simulates the creation of a Shared Bank Account which a maximum of 4 users have access to simultaneously. With all the resources and other multi-threading applications I found online, I was able to hook my current codes up.</p>
  
  <p>Here's the mentality - Each user should have equal access to the bank account without delays, deadlocks, waiting etc. Every transaction carried out (withdrawals and deposits) should be updated to the bank balance and logged. The specific transactions to be carried out for each user are stored in an array list.</p>
  
  <p>I am to make both an unsynchronized and a synchronized version of the application. I went about it by creating 4 classes - BankAccount (the bank account), BankTester (tester class to run the main app), User (the users) and UserThread (thread class for the user).</p>
  
  <p>What I have right now is the unsynchronized version of the application. Any help on how I can synchronize (and improve this unsynchronized version) it would help as I am now to Multi-threading. Thanks guys.</p>
  
  <p>Here's my code.</p>
  
  <p>BankAccount Class:</p>
  
  <pre><code>public class BankAccount {
  
  private long accountNo;
  private double accountBalance;
  
  public BankAccount() {
      this.accountNo = 9876543210L;
      this.accountBalance = 1980;
  }
  
  public void getAccountInfo() {
      System.out.println("Account Number: " + accountNo);
      System.out.println("Starting Account Balance: " + accountBalance);
  }
  
  public void getAccountBalance() {
      System.out.println("Account Balance: " + accountBalance);
  }
  
  public void deposit(double value) {
      accountBalance = (accountBalance + value);
       System.out.println("Account Balance After Deposit: " + accountBalance);
  }
  
  public void withdraw(double value) {
      accountBalance = (accountBalance + value);
      System.out.println("Account Balance After Withdrawal: " + accountBalance);
  }
  }
  </code></pre>
  
  <p>BankTest class:</p>
  
  <pre><code>import java.util.Scanner;
  
  public class BankTest {
  
  private static double[][] transactionList = {
      {50, 10, -20, 10, -20, 20, 10, 50, -10, 10, -10, 50},
      {20, 20, -20, 50, -20, 10, 50, 50, -20, 10, 10},
      {50, 10, 10, -10, -10, 50, 20, -10, -20},
      {50, 10, -20, 20, 10, -20}
  };
  
  private static BankAccount myAccount;
  
  private static UserThread myUser1;
  private static UserThread myUser2;
  private static UserThread myUser3;
  private static UserThread myUser4;
  
  public static void main(String[] args) {
  
      for (;;) {
          System.out.println("&lt;--------- Banking Menu -----------&gt;");
          System.out.println("1. Create Bank Account");
          System.out.println("2. Create User");
          System.out.println("3. Run Simulation");
          System.out.println("4. Exit");
          System.out.println("Enter choice: ");
  
          Scanner in = new Scanner(System.in);
  
          switch (in.nextInt()) {
              case 1:
                  System.out.println("&lt;--------- Create Bank Account -----------&gt;");
                  myAccount = new BankAccount();
  
                  System.out.println("Bank Account Created!");
                  break;
  
              case 2:
                  System.out.println("&lt;--------- Create User -----------&gt;");
                  System.out.println("1. User 1");
                  System.out.println("2. User 2");
                  System.out.println("3. User 3");
                  System.out.println("4. User 4");
                  userMenu();
                  break;
  
              case 3:
                  myUser1.start();
                  myUser2.start();
                  myUser3.start();
                  myUser4.start();
                  break;
  
              case 4:
                  System.out.println("Goodbye");
                  System.exit(0);
                  break;
  
              default:
                  System.err.println("Unrecognized option");
                  break;
          }
      }
  }
  
  public static void userMenu() {
      Scanner in = new Scanner(System.in);
  
      switch (in.nextInt()) {
          case 1:
              System.out.println("&lt;----- User 1 ------&gt;");
              User user1 = new User("Saul", "Goodman", myAccount, transactionList[0]);
              myUser1 = new UserThread(user1, "User 1 Thread");
              user1.getUserInfo();
              break;
  
          case 2:
              System.out.println("&lt;-------- User 2 -------&gt;");
              User user2 = new User("Walter", "White", myAccount, transactionList[1]);
              myUser2 = new UserThread(user2, "User 2 Thread");
              user2.getUserInfo();
              break;
  
          case 3:
              System.out.println("&lt;-------- User 3 -------&gt;");
              User user3 = new User("Jessie", "Pinkman", myAccount, transactionList[2]);
              myUser3 = new UserThread(user3, "User 3 Thread");
              user3.getUserInfo();
              break;
  
          case 4:
              System.out.println("&lt;-------- User 4 -------&gt;");
              User user4 = new User("Hank", "Schrader", myAccount, transactionList[3]);
              myUser4 = new UserThread(user4, "User 4 Thread");
              user4.getUserInfo();
              break;
  
          default:
              System.err.println("Unrecognized option");
              break;
      }
  }
  
  public static void runSimulation(User u) {
      double[] tList = u.getTransactionList();
      BankAccount ba = u.getBankAccount();
  
      for (int i = 0; i &lt; tList.length; i++){
          if(tList[i] &lt; 0) {
              ba.withdraw(tList[i]);
          } else{
              ba.deposit(tList[i]);
          }
          u.getName();
          ba.getAccountBalance();
      }
  }
  }
  </code></pre>
  
  <p>User class:</p>
  
  <pre><code>public class User {
  
  private String name;
  private String surname;
  private BankAccount bankAccount;
  
  private double[] transactionList;
  
  public User(String n, String s, BankAccount bA, double[] tL) {
      this.name = n;
      this.surname = s;
      this.bankAccount = bA;
      this.transactionList = tL;
  }
  
  public void getName() {
      System.out.println("Name: " + this.name);
  }
  
  public double[] getTransactionList(){
      return transactionList;
  }
  
  public void getSurname() {
      System.out.println("Surname: " + this.surname);
  }
  
  public void getUserInfo() {
      System.out.println("Full name: " + this.name + " " + this.surname);
  }
  
  public BankAccount getBankAccount() {
      return bankAccount;
  }   
  }
  </code></pre>
  
  <p>UserThread class:</p>
  
  <pre><code>public class UserThread extends Thread {
  
  private User u;
  
  public UserThread(User u, String name) {
      super(name);
      this.u = u;
  }
  
  @Override
  public void run() {
      BankTest.runSimulation(this.u);
  }
  }
  </code></pre>