首页 > 编程 > Java > 正文

Java银行取钱线程安全问题实例分析

2019-11-26 08:34:36
字体:
来源:转载
供稿:网友

本文实例讲述了Java银行取钱线程安全问题。分享给大家供大家参考,具体如下:

一 定义一个账户类

public class Account{   // 封装账户编号、账户余额的两个成员变量   private String accountNo;   private double balance;   public Account(){}   // 构造器   public Account(String accountNo , double balance)   {      this.accountNo = accountNo;      this.balance = balance;   }   // 此处省略了accountNo和balance的setter和getter方法   // accountNo的setter和getter方法   public void setAccountNo(String accountNo)   {      this.accountNo = accountNo;   }   public String getAccountNo()   {      return this.accountNo;   }   // balance的setter和getter方法   public void setBalance(double balance)   {      this.balance = balance;   }   public double getBalance()   {      return this.balance;   }   // 下面两个方法根据accountNo来重写hashCode()和equals()方法   public int hashCode()   {      return accountNo.hashCode();   }   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;   }}

二 定义一个取钱线程

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(1);        }        catch (InterruptedException ex)        {           ex.printStackTrace();        }        // 修改余额        account.setBalance(account.getBalance() - drawAmount);        System.out.println("/t余额为: " + account.getBalance());      }      else      {        System.out.println(getName() + "取钱失败!余额不足!");      }   }}

三 测试主类

public class DrawTest{   public static void main(String[] args)   {      // 创建一个账户      Account acct = new Account("1234567" , 1000);      // 模拟两个线程对同一个账户取钱      new DrawThread("甲" , acct , 800).start();      new DrawThread("乙" , acct , 800).start();   }}

四 运行

乙取钱成功!吐出钞票:800.0
甲取钱成功!吐出钞票:800.0
     余额为: 200.0
     余额为: -600.0

五 说明

账户余额只有1000时取出1600,而且账户余额出现了负数,这部是银行希望看到的结果。

虽然上面程序是人为地使用Thread.sleep(1)来强制线程调度切换,但这种切换是完全可能发生的。

更多java相关内容感兴趣的读者可查看本站专题:《Java进程与线程操作技巧总结》、《Java数据结构与算法教程》、《Java操作DOM节点技巧总结》、《Java文件与目录操作技巧汇总》和《Java缓存操作技巧汇总

希望本文所述对大家java程序设计有所帮助。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表