[英]java threads and mutual exclusion
我有以下課程來代表銀行系統:
監視者的類: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());
}
}
名為:用戶的類(線程)
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){}
}
}
}
稱為管理器的類(線程)
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){}
}
}
和主要方法
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();
}
我想要實現的是這樣的:
user1或user2開始提款(每次嘗試多次)。 可以說user1首先啟動。
如果沒有足夠的錢,請等到經理存款(嘗試存款3次或類似的東西),然后用戶1恢復提款,然后他完成用戶2之后便開始提款。
我遇到的問題:如何確保user1或user2是第一個運行的線程。 是否可以讓一個線程等待,執行另一個線程並恢復正在等待的線程?(使user1等待,執行管理器,然后恢復user1,然后執行其余的用戶?)
是否可以讓一個線程等待,執行另一個並恢復正在等待的線程
是。 您所指的是生產者-消費者問題的典型案例。
您可以通過使用synchronized
關鍵字來使用顯式同步。 使用wait
方法使線程釋放其鎖,並使用notify
方法通知線程該鎖現在可用。
您也可以使用ReenterantLock
您在這里犯的錯誤很少。
這是帶有建議更改的示例代碼
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();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.