java线程和互斥
java threads and mutual exclusion
我有以下 classes 来表示银行系统:
为班长的class: 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(线程)调用:用户
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(线程)称为经理
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 首先启动。
如果没有足够的钱等到经理存入(尝试存入三次或类似的东西)一些钱,然后用户1恢复取款然后在他完成后用户2开始取款。
我遇到的问题:
如何确保 user1 或 user2 是 运行 的第一个线程。
是否可以让一个线程等待,执行另一个线程并恢复正在等待的线程?(让 user1 等待,执行管理器然后恢复 user1,然后执行剩余的用户?)
Is it posible make a thread wait, execute another and resume the one that is waiting
是的。你说的是生产者消费者问题的经典案例。
您可以通过使用 synchronized
关键字来使用显式同步。使用 wait
方法让线程释放它的锁,并使用 notify
方法通知线程锁现在可用。
您也可以使用 ReenterantLock
你在这里犯的错误很少。
- 您的余额不是线程安全的。两个线程可以在 Withdraw 和 depositMoney 方法中更改它。因此,您可以使用互斥体 ReenterantLock,如 bot 所述。
- 如果您的执行在 wait()、Withdraw 或 depositMoney 中结束,则无法退出。为避免这种情况,您可以在每次取款或存款后调用 notifyAll()。
这是包含建议更改的示例代码
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();
}
}
我有以下 classes 来表示银行系统:
为班长的class: 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(线程)调用:用户
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(线程)称为经理
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 首先启动。
如果没有足够的钱等到经理存入(尝试存入三次或类似的东西)一些钱,然后用户1恢复取款然后在他完成后用户2开始取款。
我遇到的问题: 如何确保 user1 或 user2 是 运行 的第一个线程。 是否可以让一个线程等待,执行另一个线程并恢复正在等待的线程?(让 user1 等待,执行管理器然后恢复 user1,然后执行剩余的用户?)
Is it posible make a thread wait, execute another and resume the one that is waiting
是的。你说的是生产者消费者问题的经典案例。
您可以通过使用 synchronized
关键字来使用显式同步。使用 wait
方法让线程释放它的锁,并使用 notify
方法通知线程锁现在可用。
您也可以使用 ReenterantLock
你在这里犯的错误很少。
- 您的余额不是线程安全的。两个线程可以在 Withdraw 和 depositMoney 方法中更改它。因此,您可以使用互斥体 ReenterantLock,如 bot 所述。
- 如果您的执行在 wait()、Withdraw 或 depositMoney 中结束,则无法退出。为避免这种情况,您可以在每次取款或存款后调用 notifyAll()。
这是包含建议更改的示例代码
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();
}
}