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.
Your described scenario mirrors the usage of
static
member fields in your Account class. The keywordstatic
means that the fields are not object-bounded anymore, because they are class-bounded. So every instance of yourAccount
object will have the samestatic
field over any instance of it.To fix it you have to remove the static fields