分析:
1)账户的钱必须设置是静态的
2)所有人操作的是同一个账户,操作的时候要加同步锁
代码:
package ThreadTest;
import java.util.Objects;
public class Bank {
// 假设一个账户有1000块钱
static double money = 1000;
// 柜台Counter取钱的方法
private void Counter(double money) {
Bank.money -= money;
System.out.println("柜台取钱" + money + "元,还剩" + Bank.money + "元!");
}
// ATM取钱的方法
private void ATM(double money) {
Bank.money -= money;
System.out.println("ATM取钱" + money + "元,还剩" + Bank.money + "元!");
}
//提供一个对外取款途径,防止直接调取方法同时取款时,并发余额显示错误
public synchronized void outMoney(double money, String mode) throws Exception{
if(money > Bank.money){
//校验余额是否充足
throw new Exception("取款金额"+money+",余额只剩"+Bank.money+",取款失败");
}
if(Objects.equals(mode, "ATM")){
ATM(money);
} else {
Counter(money);
}
}
}
package ThreadTest;
public class PersonA extends Thread {
Bank bank;
String mode;
public PersonA(Bank bank, String mode) {
this.mode = mode;
this.bank = bank;
}
public void run (){
while(bank.money >= 100){
try {
bank.outMoney(100, mode);
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
package ThreadTest;
public class PersonB extends Thread {
Bank bank;
String mode;
public PersonB(Bank bank, String mode) {
this.bank = bank;
this.mode = mode;
}
public void run() {
while (bank.money >= 200) {
try {
bank.outMoney(200, mode);
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
package ThreadTest;
/**
* 两个人AB通过一个账户A在柜台取钱和B在ATM机取钱
* */
public class MainClass {
public static void main(String[] args) {
Bank bank = new Bank();
// 实例化两个人,传入同一个银行的对象
PersonA a = new PersonA(bank, "Counter");
PersonB b = new PersonB(bank, "ATM");
a.start();
b.start();
}
}
结果:
柜台取钱100.0元,还剩900.0元!
ATM取钱200.0元,还剩700.0元!
ATM取钱200.0元,还剩500.0元!
柜台取钱100.0元,还剩400.0元!
柜台取钱100.0元,还剩300.0元!
ATM取钱200.0元,还剩100.0元!
柜台取钱100.0元,还剩0.0元!