Reputation: 285
I have the following classes to represent a banking system:
The class that is a monitor: BankAccount
public class BankAccount
{
private boolean isLocked = false;
private int balance;
private String name;
private int nrWithdrawals;
public Transaction Transaction;
public BankAccount()
{
this.balance = 300;
this.name = "Bank Account";
}
public synchronized void withdraw(Transaction tran)
{
while(!canWithdraw(tran))
{
try
{
wait();
System.out.println("Not enough money: ");
}
catch( InterruptedException e) {}
}
this.setBalance((this.getBalance() - tran.getBalance()));
System.out.println("Remaining Balance is: " + this.getBalance());
}
public synchronized void depositMoney( )
{
while(this.getBalance() + 100 <= this.BankAccountLimit)
{
try
{
wait();
}
catch(InterruptedException e){}
}
this.setBalance(this.getBalance() + 100);
System.out.println("Bank Account balance is: " + this.getBalance());
}
}
A class(thread) called: User
public class User extends Thread
{
private final BankAccount account;
private ThreadGroup threadGroup;
private Transaction tran;
private String bName;
private String userName;
public User(BankAccount acc, ThreadGroup group, String name)
{
super(group, name);
this.account = acc
this.userName = name;
this.threadGroup = group;
}
public void run()
{
for(int i = 0; i< 3; i++)
{
Transaction transaction = new Transaction(70);
account.withdraw(tran);
System.out.println(this.getUserName() + " is using the bankaccount");
try
{
sleep(2000);
}
catch(InterruptedException e){}
}
}
}
A class(thread) called Manager
public class Manager extends Thread
{
private final BankAccount account;
private ThreadGroup threadGroup;
private String managerName;
public Manager(BankAccount acc, ThreadGroup tgroup, String name)
{
account = acc;
threadGroup = tgroup;
managerName = name;
}
public void run()
{
for(int i = 0; i < 3; i++)
{
account.depositMoney();
try
{
sleep(100);
System.out.println("trying....");
}
}
catch(InterruptedException e){}
}
}
and a main method
public static void main(String[] args)
{
ThreadGroup users = new ThreadGroup("Users");
ThreadGroup managers = new ThreadGroup("Managers");
BankAccount account = new BankAccount();
User user1 = new User(account, users, "User1");
User user2 = new User(account, users, "User2");
Manager manager = new Manager(account, managers, "Manager1");
user1.start();
user2.start();
manager.start();
}
What I would like to achieve would be something like this:
user1 or user2 start withdrawing money(each one try for a number of times). Lets say user1 starts first.
If there is not enough money wait until the manager deposits(tries to deposit three times or something likethis) some money and afterwards user1 resumes withdrawing money then after he finishes user2 starts withdrawing money.
The issues I have: How do I make sure that either user1 or user2 is the first thread to run. Is it posible make a thread wait, execute another and resume the one that is waiting ?(make user1 wait, execute manager then resume user1 and then execute the remaining user?)
Upvotes: 0
Views: 1044
Reputation: 1467
There are few mistakes you have done here.
Here is the sample code with the suggested alterations
public class BankAccount
{
private boolean isLocked = false;
private int balance;
private String name;
private int nrWithdrawals;
public Transaction Transaction;
private ReentrantLock lock = new ReentrantLock();
public BankAccount()
{
this.balance = 300;
this.name = "Bank Account";
}
public synchronized void Withdraw(Transaction tran)
{
lock.lock();
while(!CanWithdraw(tran))
{
try
{
lock.unlock();
System.out.println("Not enough money. Waiting for manager to deposit");
wait();
lock.lock();
}
catch( InterruptedException e) {}
}
this.setBalance((this.getBalance() - tran.getBalance()));
notifyAll();
System.out.println("Remaining Balance is: " + this.getBalance());
lock.unlock();
}
public synchronized void depositMoney( )
{
lock.lock();
while(this.getBalance() + 100 <= this.BankAccountLimit)
{
try
{
lock.unlock();
wait();
lock.lock();
}
catch(InterruptedException e){}
}
this.setBalance(this.getBalance() + 100);
notifyAll();
System.out.println("Bank Account balance is: " + this.getBalance());
lock.unlock();
}
}
Upvotes: 1
Reputation: 15212
Is it posible make a thread wait, execute another and resume the one that is waiting
Yes. What you are referring to is a classic case of the producer-consumer problem.
You can use explicit synchronization by using the synchronized
keyword. Use the wait
method to make a thread release it's locks and use the notify
method to notify threads that the lock is now available.
You can also use a ReenterantLock
Upvotes: 2