银行取钱的基本流程基本上可以分为如下几个步骤。 (1)用户输入账户、密码,系统判断用户的账户、密码是否匹配。 (2)用户输入取款密码 (3)系统判断账户余额是否大于取款余额 (4)如果余额大于取款余额,则取钱成功;如果余额小于取款余额,则取钱失败。
1、先定义一个账户类,该账户类封装了账号和余额两个实例变量。
代码语言:javascript复制public class Account {
private String accountNo;
private double balance;
public Account() {
}
public Account(String accountNo, double balance) {
super();
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(this==obj)
return true;
if(obj != null && obj.getClass() == Account.class){
Account target=(Account)obj;
return target.getAccountNo().equals(accountNo);
}
return false;
}
}
2、提供一个取钱的线程类,该线程类根据根据执行账户、取钱数量进行取钱操作,取钱的逻辑是当其余额不足时无法提取现金,当余额足够时系统吐出钞票,余额减少。
代码语言:javascript复制public class DrawThread extends Thread{
private Account account;
private double drawAmount;
public DrawThread(String name,Account account, double drawAmount) {
super(name);
this.account = account;
this.drawAmount = drawAmount;
}
public void run(){
if(account.getBalance()>=drawAmount){
System.out.println(getName() ":取钱成功!吐出钞票:" drawAmount);
try{
Thread.sleep(1000);
}catch(InterruptedException e){
e.printStackTrace();
}
account.setBalance(account.getBalance()-drawAmount);
System.out.println("t余额为:" account.getBalance());
}else{
System.out.println(getName() "取钱失败!余额不足!");
}
}
}
3、主程序创建一个账户,启动两个线程,执行取钱操作。
代码语言:javascript复制public class DrawTest {
public static void main(String[] args) {
Account acct=new Account("0329",1000);
new DrawThread("老张",acct,800).start();
new DrawThread("老王",acct,800).start();
}
}
后台输出:
老张:取钱成功!吐出钞票:800.0
老王:取钱成功!吐出钞票:800.0
余额为:200.0
余额为:-600.0
注意:程序中有两个并发线程在修改Account对象,系统恰好在try-catch处执行线程切换,切换给另一个修改Account对象的线程,所以出现了问题。
解决方案: Java的多线程支持引入了同步监视器来解决这个问题,使用同步监视器的通用方法就是同步代码块。同步代码块的语法格式如下:
代码语言:javascript复制synchronized(obj){
}
代码语言:javascript复制synchronized(account){
if(account.getBalance()>=drawAmount){
System.out.println(getName() ":取钱成功!吐出钞票:" drawAmount);
try{
Thread.sleep(1000);
}catch(InterruptedException e){
e.printStackTrace();
}
account.setBalance(account.getBalance()-drawAmount);
System.out.println("t余额为:" account.getBalance());
}else{
System.out.println(getName() "取钱失败!余额不足!");
}
}
控制台输出:
代码语言:javascript复制 老张:取钱成功!吐出钞票:800.0
余额为:200.0
老王取钱失败!余额不足!