取票是因为一个对象开启了三个线程,所以直接锁方法就行了,但是取钱是两个对象分别开了一个线程,所以你直接锁run方法没有用,这时就只能锁公共资源
package com.kuang.Demo07同步方法以及同步块;
//模拟银行取钱
public class UnSafeDrawMoney {
public static void main(String[] args) {
Account account = new Account(100,"结婚基金");
Drawing you = new Drawing(account,50,"you");
Drawing girl= new Drawing(account,100,"girl");
you.start();
girl.start();
}
}
class Account {
int money;
String name;
public Account(int money, String name) {
this.money = money;
this.name = name;
}
}
class Drawing extends Thread{
Account account;//账户
// 取了多少钱
int drawingMoney;
// 现在手里有多少钱
int nowMoney;
public Drawing(Account account, int drawingMoney,String name){
//调用父类构造方法,放入名字
super(name);
this.account=account;
this.drawingMoney=drawingMoney;
}
@Override
public void run() {
synchronized (account){
if (account.money-drawingMoney<0){
System.out.println(Thread.currentThread().getName()+"的钱不够,取不了");
return;
}
try {
// sleep放大问题的发生性!
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 卡内余额=余额-取走的钱
account.money=account.money-drawingMoney;
// 现有的钱=之前的钱+取走的钱
nowMoney=nowMoney+drawingMoney;
System.out.println(account.name+"余额为:"+account.money);
// this.getName()==Thread.currentThread().getName()
System.out.println(this.getName()+"手里的钱:"+nowMoney);
}
}
}