模拟提款存款的一个例子

今天在JavaWorld.tw论坛上看到一个求提款和存款的帖子(http://www.javaworld.com.tw/jute/post/view?bid=29&id=247594&sty=1&tpg=1&age=0),自己写了个例子,加深对Java Thread的学习和理解:

package cn.xbmu.lib.jfly.test;

import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * A:帳戶類別:
設計提款功能,每次可以提出100元,但是當帳戶餘額為0,不可以再提款。
設計存款功能,每次可以存入1000元,但是當帳戶餘額不為0,不可以再存款。

B:提款類別:在此類別中執行「提款」的功能。

C:存款類別:在此類別中執行「存款」的功能。

D:主程是要啟動使用「提款類別」和「存款類別」兩個執行緒。 
 * @author JFly
 */
public class MySaveAndGet {

    public static void main(String[] args) throws InterruptedException {
        Account acc = new Account();
        PutMoney pm = new PutMoney(acc);
        TakeMoney tm = new TakeMoney(acc);
        pm.start();
        tm.start();

        Thread.sleep(5000);   // 模拟动作执行5秒
        synchronized(pm) {
            pm.close = true;
            pm.notifyAll();
        }
        synchronized(tm) {
            tm.close = true;
            tm.notifyAll();
        }
    }
}

class Account {
    int m;      // 帐户余额
    boolean t_or_p = false;     // 提款或者存款,false存款,true提款

     void takeM() {
        if (m == 0) {
            System.out.println("帐户余额为0,不可以再提款!");
        } else {
            m = m - 100;
            System.out.println("取出后剩余 " + m);
        }
        t_or_p = true;          // 提款动作
    }

     void putM() {
        if (m != 0) {
            System.out.println("帐户余额不为0,不可以再存款!");
        } else {
            m = m + 1000;
            System.out.println("存入后剩余 " + m);
        }
        t_or_p = false;       // 存款动作
    }
}

class PutMoney extends Thread {

    Account acc = null;
    boolean close = false;

    public PutMoney(Account acc) {
        this.acc = acc;
    }

    @Override
    public void run() {
        while (true) {      // 模拟存款
            synchronized (acc) {
                while (!acc.t_or_p) {
                    try {
                        acc.wait();
                    } catch (InterruptedException ex) {
                        Logger.getLogger(PutMoney.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
                if(close) {
                    break;
                }
                acc.putM();
                acc.notifyAll();
            }
        }
    }
}

class TakeMoney extends Thread {

    Account acc = null;
    boolean close = false;

    public TakeMoney(Account acc) {
        this.acc = acc;
    }

    @Override
    public void run() {
        while (true) {      // 模拟提款
            synchronized (acc) {
                while (acc.t_or_p) {
                    try {
                        acc.wait();
                    } catch (InterruptedException ex) {
                        Logger.getLogger(TakeMoney.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
                if(close) {
                    break;
                }
                acc.takeM();
                acc.notifyAll();
            }
        }
    }
}

 

### Java 实现 ATM 柜员机模拟程序 #### 创建 Bank 类用于管理账户信息 为了实现一个完整的ATM系统,首先需要创建`Bank`类来管理和存储用户的银行账户信息。 ```java import java.util.HashMap; import java.util.Map; public class Bank { private Map<String, Account> accounts = new HashMap<>(); public void addAccount(Account account) { accounts.put(account.getAccountNumber(), account); } public boolean authenticate(String accountNumber, String pin) { var account = accounts.get(accountNumber); if (account != null && account.validatePin(pin)) { return true; } return false; } public double getBalance(String accountNumber) { return accounts.get(accountNumber).getBalance(); } public void withdraw(String accountNumber, double amount) { accounts.get(accountNumber).withdraw(amount); } public void deposit(String accountNumber, double amount) { accounts.get(accountNumber).deposit(amount); } } ``` 此部分展示了如何定义一个简单的`Bank`类[^1]。该类负责维护一系列账户对象,并提供基本的操作接口如验证登录、查询余额以及存取款等功能。 #### 定义 Account 类表示具体账户实体 接着定义`Account`类作为单个客户账户的具体表现形式: ```java public class Account { private final String accountNumber; private final String pin; private double balance; public Account(String accountNumber, String pin, double initialDeposit) { this.accountNumber = accountNumber; this.pin = pin; this.balance = initialDeposit; } public String getAccountNumber() {return accountNumber;} public boolean validatePin(String enteredPin) { return pin.equals(enteredPin); } public synchronized void withdraw(double amount) { if (amount <= balance) { balance -= amount; } else { throw new IllegalArgumentException("Insufficient funds"); } } public synchronized void deposit(double amount) { if (amount > 0) { balance += amount; } else { throw new IllegalArgumentException("Invalid deposit amount"); } } public double getBalance() { return balance; } } ``` 这段代码实现了具体的账户行为,包括初始化时设置账号密码及初始存款金额;提供了校验PIN码的方法;还有同步控制下的提款存款功能以防止并发访问带来的问题。 #### 构建图形界面(GUI) 对于更友好的用户体验来说,可以采用Swing库构建图形化用户界面(GUI),使得操作更加直观方便。下面是一个简化版的主窗口设计示例: ```java import javax.swing.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; public class ATMMachine extends JFrame implements ActionListener { private JTextField txtAccountNo; private JPasswordField pwdField; private JButton btnLogin; private JLabel lblMessage; // ... GUI组件声明... public static void main(String[] args){ EventQueue.invokeLater(() -> { try { UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName()); ATMMachine frame = new ATMMachine(); frame.setVisible(true); } catch (Exception e) { e.printStackTrace(); } }); } @Override public void actionPerformed(ActionEvent event) { Object source = event.getSource(); if(source == btnLogin){ String accNum = txtAccountNo.getText().trim(); char[] passwordChars = pwdField.getPassword(); String passStr = new String(passwordChars); if(bank.authenticate(accNum,passStr)){ JOptionPane.showMessageDialog(this,"Welcome!"); dispose(); // 关闭当前窗体 // 打开新页面... }else{ lblMessage.setText("Incorrect credentials."); } pwdField.setText(""); } // 处理其他按钮点击事件... } } ``` 这里给出了一个基础框架,其中包含了登录认证的功能。当用户输入正确的凭证后会显示欢迎消息并跳转到下一个操作界面,在实际应用中还需要继续完善各个子模块之间的导航逻辑[^2]。 #### 数据持久层连接数据库 最后要提到的是数据持久性的解决方案。通常情况下我们会选择关系型数据库管理系统(RDBMS)来进行长期的数据保存工作。利用Apache Commons DbUtils工具包中的QueryRunner可以帮助快速执行SQL语句而无需手动处理资源关闭等问题: ```java // 假设已经配置好了Druid连接池 QueryRunner queryRunner = new QueryRunner(DruidUtils.getDataSource()); String sql = "INSERT INTO Accounts VALUES (?, ?, ?)"; Object[] params = {"ACC123", "PASSWD", 500}; try { int affectedRows = queryRunner.update(sql, params); } catch (SQLException ex) { Logger.getLogger(ATMMachine.class.getName()).log(Level.SEVERE, null, ex); } ``` 上述片段说明了怎样借助DbUtils完成向表内插入记录的任务。当然这只是一个非常粗略的例子,真实环境中应当考虑更多因素比如异常捕获机制、事务管理等[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值