多线程编程常常会出现各种安全问题,银行取钱是一个经典的线程安全问题。
public class Account {
private String accountNo;
private double balance;
public Account() {}
public Account(String accountNo, double balance) {
this.accountNo = accountNo;
this.balance = balance;
}
public String getAccountNo() {
return accountNo;
}
public void setAccountNo(String accountNo) {
this.accountNo = accountNo;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
@Override
public int hashCode() {
return accountNo.hashCode();
}
@Override
public boolean equals(Object obj) {
if(obj == this)
return true;
if(obj != null && obj.getClass() == Account.class) {
Account target = (Account)obj;
return target.getAccountNo().equals(accountNo);
}
return false;
}
}
public class DrawThread extends Thread {
private Account account;
// The amount of money that client want to draw
private double drawAmount;
public DrawThread(String name, Account account, double drawAmount) {
super(name);
this.account = account;
this.drawAmount = drawAmount;
}
@Override
public void run() {
if (account.getBalance() >= drawAmount) {
System.out.println(getName() + " draw money:" + drawAmount);
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
account.setBalance(account.getBalance() - drawAmount);
System.out.println("The blance is:" + account.getBalance());
} else {
System.out.println(getName() + "The blance is not enough!");
}
}
}
public class DrawTest {
public static void main(String[] args) {
Account acct = new Account("123", 10000);
new DrawThread("A", acct, 8000).start();
new DrawThread("B", acct, 8000).start();
}
}上面的程序可能出现各种结果,可运行观察之。其中一个结果如下,账户被取了比余额更多的钱,这显然是不可接受的。
A draw money:8000.0 B draw money:8000.0 The blance is:2000.0 The blance is:-6000.0

京公网安备 11010502036488号