线程问题分析

在学习多线程的时候,有一个比较经典的例子是讲银行里的账号,假如存在多位取款者及存款者,在这里就涉及到线程锁及线程之间的通讯,但大部分的例子人讲了金额为1000,每次存取只有800,并且存完了就通知取的人,取完了就通知存的人。存款人及取款人均为一位。
个人在模拟这个问题的时候有将问题复杂化,假定有多位存款者,及取款者,当余额<=要取的钱的时候取款者不能取款,而当余额+ 存款值大于某一个值的时候不允许存款。

账户中存取款方法的代码

public synchronized void draw(double drawAccount){
        try{
            if(drawAccount > blance){
                System.out.println(Thread.currentThread().getName() + "余额不足");
                wait();
            }
            else{
                System.out.println("\t" + Thread.currentThread().getName() + "取钱" + drawAccount);
                blance -= drawAccount;
                System.out.println("\t" + "账号余额: " + blance);
                if(drawAccount > blance){
                    notifyAll();
                }
            }
        }catch (InterruptedException ie){
            ie.printStackTrace();
        }
    }

    public synchronized void deposit(double depositAccout){
        try{
            if((blance + depositAccout) > total){
                System.out.println(Thread.currentThread().getName() + "已到最高");
                wait();
            }else{
                System.out.println(Thread.currentThread().getName() + "存钱" + depositAccout);
                blance += depositAccout;
                System.out.println("账号余额" + blance);
                if((blance + depositAccout) > total){
                    notifyAll();
                }
            }
        }catch (InterruptedException ie){
            ie.printStackTrace();
        }
    }

取款线程

取款5次

public void run(){
        for(int i = 0; i < 5; i++){
            //System.out.println(getName() + "取钱");
            System.out.println("\t" + getName() + i);
            account.draw(drawAccount);
        }
    }

存款线程

存款5次

public void run(){
        for(int i = 0; i < 5; i++){
            //System.out.println(getName() + "存钱");
            System.out.println(getName() + i);
            account.deposit(depositAccount);
        }
    }

主线程

模拟2位取款者及2位取款者

public class DrawTest {
    public static void main(String[] args) {
        Account acct = new Account("12345", 1000);
        new DrawThread("取钱者c", acct, 800).start();
        new DrawThread("取钱者d", acct, 800).start();
        new DepositThread("存钱者A", acct, 800).start();
        new DepositThread("存钱者B", acct, 800).start();

    }

}

按照我最开始的理解,最后的余额应该为1000才对,因为2位取款者各取5次,2位存款者各存5次。
但实际运行结果通常都不是1000

例如 :

账号余额: 1800.0

这说明某位取款者少取了 一次,后来对于每个取款者的每次操作打印分析,发现以下一点:

取钱者d3
取钱者d余额不足
取钱者d4
取钱者d取钱800.0
账号余额: 1800.0

问题就了在这里,取款者d在进行第4次取款的时候失败,也就是说if为真没有进入到else里面,但for循环还是将其算作一次取款,所以才导致最终的余额不为1000。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值