多线程模拟银行取钱的问题

1.模拟银行取钱的问题
1.定义一个Account类
1)该Account类封装了账户编号(String)和余额(double)两个属性
2)设置相应属性的getter和setter方法
3)提供无参和有两个参数的构造器
4)系统根据账号判断与用户是否匹配,需提供hashCode()和equals()方法的重写
在我们重写hashCode()方法后,可以看到两个属性值完全相同的对象,他们的哈希值是相同的。从业务的角度来说,达到了这两个对象相同的目的。
2.提供两个取钱的线程类:小明、小明’s wife
1)提供了Account类的account属性和double类的取款额的属性
2)提供带线程名的构造器
3)run()方法中提供取钱的操作
3.在主类中创建线程进行测试。考虑线程安全问题。

  1. 利用lock和接口Runnable
package com.lianxi.thread;

import java.util.concurrent.locks.ReentrantLock;

public class Account2 {
    private final ReentrantLock lock=new ReentrantLock(true);
    private String id;
    private double balance;
    public void setBalance(double balance) {
        this.balance = balance;
    }
    public double getBalance() {
        return balance;
    }
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public Account2(String id,double balance){
        this.balance=balance;
        this.id=id;
    }
    public Account2(){
    }

    @Override
    public int hashCode() {
        final int a=31;
        int result=1;
        result =a*result+((id==null)?0:id.toUpperCase().hashCode());
        long temp;
        temp=Double.doubleToLongBits(balance);
        result=a*result+(int)(temp^(temp>>>32));
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj==this){
            return obj==this;
        }
        if (obj instanceof Account2){
            Account2 account2= (Account2) obj;
            return this.id.equals(account2.id);
        }
        return false;
    }

    @Override
    public String toString() {
        return "账户编号:"+id+",余额:"+balance;
    }
    public void save(double money){
        lock.lock();
        try {
            if (money > 0&&balance >= money) {
                balance-=money;
                System.out.println(Thread.currentThread().getName() + ":取款成功,取款金额为:" + money);
            } else {
                System.out.println(Thread.currentThread().getName()+"取款失败,余额不足");
            }
        }finally {
            System.out.println("账户编号:"+id+",余额:"+balance);
            lock.unlock();
        }
    }
}
class WithdrawMoney2 implements Runnable{
    public Account2 account2;
    public Thread thread;
    private double money;//取款金额
    public WithdrawMoney2(Account2 account2,double money){
        this.account2=account2;
        this.money=money;
    }
    @Override
    public void run() {
        account2.save(money);
    }
}
class AccountTest{
    public static void main(String[] args){
        Account2 account2=new Account2("2003",2000);
        WithdrawMoney2 w1=new WithdrawMoney2(account2,200);
        WithdrawMoney2 w2=new WithdrawMoney2(account2,300);
        WithdrawMoney2 w3=new WithdrawMoney2(account2,300);
        Thread t1=new Thread(w1);
        Thread t2=new Thread(w2);
        Thread t3=new Thread(w3);
        t1.setName("lilining");
        t2.setName("zhengzijun");
        t3.setName("3");
        t1.start();
        t2.start();
        t3.start();
        //System.out.println(account2);
    }
}
  1. 利用继承Thread和synchronized
package com.lianxi.thread;

public class Account {
    private String id;//账户编号
    private double balance;//余额
    public Account(){//无参构造器
    }
    public Account(String id,double balance){//有参构造器
        this.balance=balance;
        this.id=id;
    }
    public String getId() {
        return id;
    }
    public void setId(String id){
        this.id=id;
    }
    public double getBalance(){
        return balance;
    }
    public void setBalance(double balance) {
        this.balance = balance;
    }

    /**
     * 在我们重写hashCode()方法后,可以看到两个属性值完全相同的对象,
     * 他们的哈希值是相同的。从业务的角度来说,达到了这两个对象相同的目的。
     * toUpperCase()--转换为大写的字符串
     * @return
     */
    @Override
    public int hashCode() {
        final int p=31;
        int a=1;
        a=p*a+((id==null)?0:id.toUpperCase().hashCode());
        return a;
    }

    /**
     * 系统根据账号判断与用户是否匹配
     * @param obj
     * @return
     */
    @Override
    public boolean equals(Object obj) {
        //地址相等
        if (this==obj){
            return this==obj;
        }
        //如果两个对象的账户编号相等,我们认为相等
        if (obj instanceof Account) {
            Account a = (Account) obj;
            return this.id.equals(a.id);
        }
        return false;
    }

class WithdrawMoney extends Thread{
    Account account;
    private double money;//取款金额
    public WithdrawMoney(){
    }
    public WithdrawMoney(String name,Account account,double money){
        super(name);
        this.account=account;
        this.money=money;
    }
    public double getMoney() {
        return money;
    }
    public void setMoney(double money) {
        this.money = money;
    }
    @Override
    public void run() {
        synchronized (account) {
            if (account.getBalance() > 0 && account.getBalance() >=money) {
                System.out.println(Thread.currentThread().getName()+":取款成功,取款金额为:"+money);
                try {
                    Thread.sleep(100);
                }catch (InterruptedException e){
                    e.printStackTrace();
                }
                account.setBalance(account.getBalance() - money);
            } else {
                System.out.println("余额不足");
            }
            System.out.println("现在账户的余额为:"+account.getBalance());
        }
    }
}
class AccountText{
    public static void main(String[] args){
        Account a=new Account("10001",2000);
        WithdrawMoney w1=new WithdrawMoney("小明",a,2000);
        WithdrawMoney w2=new WithdrawMoney("小明老婆",a,300);
        w1.start();
        w2.start();

    }
}

  • 13
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值