Thread之 模拟多银行多窗口多用户存取钱
- 实现多窗口取钱操作
- 实现多窗口存取操作
- 实现存取的同步
- 当账号余额到一定额度限制存取操作的暂停和继续
方法摘要
- start()线程就绪
- synchronized()线程执行同步代码块
- wait() 线程等待
- notifyAll() 唤醒 所有此对象监视器上的等待线程
代码实现如下
此模块实现 主线程创建三个取钱 两个存钱线程对象
public static void main(String[] args) {
// 创建一个银行账户并用构造初始化赋值 账号 余额
Account account = new Account("95599 001", 5000);
//创建三个取钱的线程对象传入参数 取钱用户名 账户对象 取钱额
Withdraw w1 = new Withdraw("张三", account, 1000);
Withdraw w2 = new Withdraw("李四", account, 3000);
Withdraw w3 = new Withdraw("王五", account, 4000);
//创建两个存钱的线程对象传入参数 存钱用户名 账户对象 存钱额
SaveMoney s1 = new SaveMoney("圆圆", account, 5000);
SaveMoney s2 = new SaveMoney("方方", account, 1000);
//就绪三个取钱线程和两个存钱线程
w1.start();
w2.start();
w3.start();
s1.start();
s2.start();
}
此模块实现 存钱线程的创建
class SaveMoney extends Thread {
private double money;
private Account account;
/**
* 构造
*
* @param threadName
* 线程名称
* @param account
* 操作的账户对象
* @param money
* 要取的钱数
*/
public SaveMoney(String threadName, Account account, double money) {
super(threadName);// 为当前线程设置名称
this.account = account;
this.money = money;
}
@Override
public void run() {
while (true) {
//此处实现同步代码块保证线程操作完整执行
synchronized (account) {
if (account.getBalance()>=10000) {
try {
account.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
account.setBalance(account.getBalance() + money);// 存钱成功
System.out.println(Thread.currentThread().getName()
+ ",存了一笔大钱-" + money + ",,目前账户余额是:"
+ account.getBalance());
account.notifyAll();
}
}
}
}
}
此模块实现 取钱线程的创建
class Withdraw extends Thread {
private double money;
private Account account;
/**
* 构造
*
* @param threadName
* 线程名称
* @param account
* 操作的账户对象
* @param money
* 要取的钱数
*/
public Withdraw(String threadName, Account account, double money) {
super(threadName);// 为当前线程设置名称
this.account = account;
this.money = money;
}
@Override
public void run() {
while (true) {
//此处实现同步代码块保证线程操作完整执行
synchronized (account) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (account.getBalance() < money) {// 余额不足
System.out.println(Thread.currentThread().getName()
+ " 取钱中,打算取" + money + "结果:余额不足");
try {
account.wait();//余额不足,需要等待
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
account.setBalance(account.getBalance() - money);// 更改余额
System.out.println(Thread.currentThread().getName()
+ " 取钱中,取了" + money + ",余额:" + account.getBalance());
//唤醒 所有此对象监视器上的等待线程
account.notifyAll();
}
}
}
}
}
此模块实现 银行账户实体类的封装
重写equals() 和 hashCode()方法
class Account {
private String id;
private double balance;
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (!(obj instanceof Account)) {
return false;
}
Account acc = (Account) obj;
return acc.id.equals(this.id);
}
@Override
public int hashCode() {
return id.hashCode();
}
public Account() {
}
public Account(String id, double balance) {
super();
this.id = id;
this.balance = balance;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
}