银行取钱操作
定义账户类—临界资源
定义取钱线程
public class 取钱线程 extends Thread {
private 账户类 account;//取钱的账户
private double amount;//取钱的金额
public 取钱线程(账户类 account,double amount) {
this.account=account;
this.amount=amount;
}
@Override
public void run() {
//首先判断余额是否满足
if(account.getBalance()>amount) {
//阻塞200ms,模拟取钱过程
try {
Thread.sleep(200); //不会释放锁
} catch (InterruptedException e) {
e.printStackTrace();
}
//调用账户类的方法实现取钱处理
account.setBalance(account.getBalance()-amount);
}
}
}
存钱线程,用于模拟银行发工资。上账时间1000ms
public class 存钱线程 implements Runnable {
private 账户类 account;
private double amount;
public 存钱线程(账户类 account,double salary) {
this.account=account;
this.amount=salary;
}
@Override
public void run() {
double dd=account.getBalance();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
dd+=amount;
account.setBalance(dd);
}
}
定义主方法,模拟出现了针对同一个账户同时取钱和发钱的过程
账户类 account=new 账户类(1L, 10000.);
取钱线程 t1=new 取钱线程(account, 9000);
存钱线程 t2=new 存钱线程(account,500.);
t1.start(); t2.start();
t1.join();
t2.join();
System.out.println(account.getBalance());
显示结果为10500.0,执行结果错误?
- 共享同一个账户
- 执行修改操作,但是没有进行同步约束
如果解决出现的错误:使用同步处理—synchronized—加锁
最简单的方法:
使用方法2的同步代码块,在修改操作上添加对应的同步处理
public void run() {
synchronized (account) { //同步上下文
//首先判断余额是否满足
if(account.getBalance()>amount) {
//阻塞200ms,模拟取钱过程
try {
Thread.sleep(200); //不会释放锁
} catch (InterruptedException e) {
e.printStackTrace();
}
//调用账户类的方法实现取钱处理
account.setBalance(account.getBalance()-amount);
}
}
}
最常见的比较好想的方法:
使用方法1的同步方法
public class 账户类 {
private Long id;
private Double balance;
public 账户类(long l, double d) {
this.id = l;
this.balance = d;
}
public synchronized void 存钱(double salary) {
double dd = balance;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
dd += salary;
this.balance = dd;
}
public synchronized void 取钱(double amount) {
// 首先判断余额是否满足
if (balance > amount) {
// 阻塞200ms,模拟取钱过程
try {
Thread.sleep(200); // 不会释放锁
} catch (InterruptedException e) {
e.printStackTrace();
}
// 调用账户类的方法实现取钱处理
this.balance = this.balance - amount;
}
}
public Double getBalance() {
return this.balance;
}
}