线程练习

1:  

银行有一个账户。有两个储户分别向同一个账户存3000元,每次存1000,存3次。每次存完打
印账户余额。

问题:该程序是否有安全问题,如果有,如何解决?

【提示】 1,明确哪些代码是多线程运行代码,须写入run()方法 2,明确什么是共享数据。 3,明确多线程运行代码中哪些语句是操作共享数据的。

 

 

解答

public class LianxiTest {
    public static void main(String[] args) {
        Accoun accoun = new Accoun(0);
        BankL bankL1 = new BankL(accoun);
        BankL bankL2 = new BankL(accoun);
        bankL1.start();
        bankL2.start();
    }
}


class BankL extends  Thread{

    private  Accoun accoun;

    public  BankL(Accoun accoun){
        this.accoun = accoun;
    }

    @Override
    public void run() {
        for(int i = 0; i < 3; i++){
            accoun.deposit(1000);
        }
    }
}

class Accoun{

    private double balance;

    public  Accoun(double balance){
        this.balance = balance;
    }

    public   synchronized  void deposit(double amt){
        if( amt > 0){
            balance += amt;
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+":  存了钱 余额为: "+balance);
        }
    }
}
使用继承Thread类的synchronized方式

 

 

 

2: 

1.定义一个Account类
练习2
1)该Account类封装了账户编号(String)和余额(double)两个属性
2)设置相应属性的getter和setter方法
3)提供无参和有两个参数的构造器
4)系统根据账号判断与用户是否匹配,需提供hashCode()和equals()方法的重写
2.提供两个取钱的线程类:小明、小明’s wife
   1)提供了Account类的account属性和double类的取款额的属性
   2)提供带线程名的构造器
   3)run()方法中提供取钱的操作
3.在主类中创建线程进行测试。考虑线程安全问题。

 

 

 

 

mport java.util.Objects;

public class BankTestOneOne {
    public static void main(String[] args) {
        AccountTOne accountTOne = new AccountTOne("001", 1000);

        WithDrawThread withDrawThread = new WithDrawThread("老王", accountTOne, 500);
        withDrawThread.start();

        AccountTOne accountTOne1 = new AccountTOne("002", 2000);
        WithDrawThread withDrawThread1 = new WithDrawThread("老李", accountTOne1, 300);
        withDrawThread1.start();
    }
}



class AccountTOne{
    private  String accountId;  // 账号
    private double balance;  // 余额

    public  AccountTOne(){};

    public  AccountTOne(String accountId, double balance){
        this.balance = balance;
        this.accountId = accountId;
    }


    public String getNumber() {
        return accountId;
    }

    public void setNumber(String accountId) {
        this.accountId = accountId;
    }

    public double getBalance() {
        return balance;
    }

    public void setBalance(double balance) {
        this.balance = balance;
    }

    @Override
    public String toString() {
        return "AccountTOne{" +
                "accountId='" + accountId + '\'' +
                ", balance=" + balance +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        AccountTOne that = (AccountTOne) o;
        return Double.compare(that.balance, balance) == 0 &&
                Objects.equals(accountId, that.accountId);
    }

    @Override
    public int hashCode() {
        return Objects.hash(accountId, balance);
    }
}



class  WithDrawThread extends Thread{


    private  AccountTOne accountTOne;
    //设置取款额度

    private  double withDraw;

    public  WithDrawThread(){};
    public WithDrawThread(String name,AccountTOne accountTOne, double withDraw){
        super(name);
        this.accountTOne = accountTOne;
        this.withDraw = withDraw;
    }

    @Override
    public void run() {
        synchronized(accountTOne){
            if(accountTOne.getBalance() > withDraw){
                System.out.println(Thread.currentThread().getName()+"取款成功, 金额为:"+withDraw);
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                accountTOne.setBalance(accountTOne.getBalance()- withDraw);  // 剩余钱数
            }else{
                System.out.println("取款金额超出上限");
            }
            System.out.println(Thread.currentThread().getName()+"现在的余额为: "+ accountTOne.getBalance());
        }
    }
}
银行账号取钱的操作

 

posted @ 2019-11-13 21:01  可爱的红领巾  阅读(270)  评论(0编辑  收藏  举报