当前位置: 首页 > 编程笔记 >

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

高嘉熙
2023-03-14
本文向大家介绍Java银行取钱线程安全问题实例分析,包括了Java银行取钱线程安全问题实例分析的使用技巧和注意事项,需要的朋友参考一下

本文实例讲述了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程序设计有所帮助。

 类似资料:
  • 本文向大家介绍Java使用同步方法解决银行取钱的安全问题案例分析,包括了Java使用同步方法解决银行取钱的安全问题案例分析的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Java使用同步方法解决银行取钱的安全问题。分享给大家供大家参考,具体如下: 一 点睛 与同步代码块对应,Java的多线程安全支持还提供了同步方法,同步方法就是使用synchronized关键字来修饰某个方法,则该方法称为

  • 本文向大家介绍Java 单例模式线程安全问题,包括了Java 单例模式线程安全问题的使用技巧和注意事项,需要的朋友参考一下 Java 单例模式线程安全问题 SpringIOC容器默认提供bean的访问作用域是单例模式。即在整个application生命周期中,只有一个instance。因此在多线程并发下,会有线程安全风险。我们在MVC框架下的servlet就是线程安全的。由于该servlet是在客

  • 本文向大家介绍如何实现Java线程安全问题,包括了如何实现Java线程安全问题的使用技巧和注意事项,需要的朋友参考一下 这篇文章主要介绍了如何实现Java线程安全问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 解决线程安全问题的第一种方案:使用同步代码块 格式:   synchronized(锁对象) {     可能会出现线程安全问题的代码

  • 本文向大家介绍实例解析Java中的synchronized关键字与线程安全问题,包括了实例解析Java中的synchronized关键字与线程安全问题的使用技巧和注意事项,需要的朋友参考一下 首先来回顾一下synchronized的基本使用: synchronized代码块,被修饰的代码成为同步语句块,其作用的范围是调用这个代码块的对象,我们在用synchronized关键字的时候,能缩小代码段的

  • When using any of the threaded mpms in Apache 2.0 it is important that every function called from Apache be thread safe. When linking in 3rd party extensions it can be difficult to determine whether t

  • 问题内容: 我写了下面的Singleton类。我不确定这是否是线程安全的单例类吗? 谁能帮我这个?我在上述Singleton课堂上的任何想法都会有很大帮助。 更新代码: 我正在尝试将波希米亚建议纳入我的代码中。这是更新的代码,我得到了- 谁能看一下,让我知道这次是否正确? 问题答案: 但是有一个简单的技巧,可以让你的代码是线程安全的实现,并不需要同步!它称为“ 按需初始化持有人”习惯用法,它看起来