银行取钱线程安全问题x

来源:司法考试 发布时间:2020-09-07 点击:

 银行取钱线程安全问题 一 定义一个账户类 定义一个账户类 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)来强制线程调度切换,但这种切换是完全可能发生的。

推荐访问:线程 安全问题 取钱
上一篇:江苏省姜堰市第二中学人民版高中历史必修二教案:专题二,第三节,中国资本主义产生2
下一篇:江苏公务员申论真题及参考答案(A)

Copyright @ 2013 - 2018 优秀啊教育网 All Rights Reserved

优秀啊教育网 版权所有