实现实际问题到代码的抽象

问题背景:某人在银行里开设了账户,现在要模拟往这个银行里存钱和取钱的操作。

问题分析:这个问题里设计的变量有:

                          银行账户余额:当我们在账户余额操作时,出于安全以及现实的因素考虑,一个时候只能有一个动作访问这个账户余额。

                     涉及的动作有:

                           往银行里存钱:一次只能有一个人往银行里存钱,取钱动作不与存钱动作同时发生。

                           从银行里取钱:一次只能有一个人往银行里存钱,取钱不能与存钱的动作同时发生。



问题抽象:

                      账户余额是一个变量,且这个变量不能被两个不同的动作同时访问,因此它是临界资源(操作系统中的概念),若是执行对他的操作,必须是同步(线程协同工作,   按 照不同的顺序访问它)的。

                       存钱和取钱是两个动作,这两个动作在两个不同的线程中执行(计算机代码必须在一个线程中才能执行),由于这两个线程中的代码都需要访问账户这个变量,所以

这两个线程需要同步执行,即当我们的存钱线程在进行时(存钱线程被CPU调度),给临界资源加锁,当另外一个线程需要访问账户余额这个临街资源时,会先检查这个临界资源是否被“锁上了”,如果锁上了,就进入等待队列,等待这个“锁”被解除,一但这个锁被解除,上一个线程结束,等待队列里面的等待线程激活,进入执行状态,并再次给临界资源加锁,周而复始,直到所有线程执行完成。

  
如下是我的代码,其中不仅仅有关于线程的知识点,也有一些关于java堆栈的分析过程。

package practice34;

import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;


public class bankThread extends JFrame{
    
    
    //在这里声明一些引用,相当于是声明了一些指针,作为总体变量,后面即使在不同的方
    //法体中为他们申请实际内存(建立实例),也可以在整个实例中被访问
    private JPanel contentpane;
    private JTextArea textarea;
    private JButton button;
    private Font font=new Font("微软雅黑",Font.PLAIN,16);
    
    /**
     * the constructor
     */
    public bankThread(){
        setTitle("银行模拟器");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setBounds(400,400,400,400);
        contentpane=new JPanel();
        setContentPane(contentpane);
        contentpane.setLayout(new GridLayout(3,1));
        
        JLabel label=new JLabel("以下内容表示银行的存取过程");
        label.setFont(font);
        
        textarea = new JTextArea();
        contentpane.add(textarea);
        
        button=new JButton("开始模拟");
        button.setFont(font);
        button.addActionListener(new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                do_button_action(e);
            }            
        });
        
        contentpane.add(label);
        contentpane.add(textarea);
        contentpane.add(button);
    }
    
    private class Bank {
        private int account = 100;
        
        //the method is used to add the money
        public void addMoney(int money) {
            synchronized (this) {// 获得Bank类的锁
                account += money;
            }
        }
        
        //the method is used to reduce money
        public void reduceMoney(int money){
            synchronized (this) {// 获得Bank类的锁
                account += money;
            }           
        }
        
        public int getAccount() {
            return account;
        }
    }
    
    /**
     * the program will be executed when you click the button
     */
    protected void do_button_action(ActionEvent e){
        Bank bank=new Bank();
        Thread thread1 = new Thread(new Transfer(bank, 0));
        thread1.start();
        Thread thread2 = new Thread(new Transfer(bank, 1));
        thread2.start();
        
    }
   
    private class Transfer implements Runnable{
        
        //这个类用来对银行存款进行操作,但是银行的存款余额变量
        //是在另一个方法中自定义的,因此,需要一个指向外部的指针
        //从而在本方法中对其进行访问
        private Bank bank;
        private int flag;
        
        public Transfer(Bank bank,int flag){
            this.bank=bank;
            this.flag=flag;
        }

    @Override
     public void run() {
        // TODO Auto-generated method stub
        if(flag==1){
            for(int i=0;i<10;i++){
                bank.addMoney(10);
                String text=textarea.getText();
                textarea.setText(text+"账户余额是"+bank.getAccount());
            }            
        }else if(flag==0){
            for(int i=0;i<10;i++){
                bank.reduceMoney(10);
                String text=textarea.getText();
                textarea.setText(text+"账户余额是"+bank.getAccount());            
            }
        }        
     }       
   }
    
    /**
     * launch the application
     */
    public static void main(String args[]){
        bankThread frame=new bankThread();
        frame.setVisible(true);
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的 C++ 实现实现了基本的 SPL 抽象语法树节点,并提供了一些示例方法: ```cpp #include <iostream> #include <string> #include <vector> using namespace std; // SPL 抽象语法树节点类 class SplAstNode { public: virtual ~SplAstNode() {} virtual string getType() const = 0; virtual void print() const = 0; }; // 整数字面量节点类 class IntLiteral : public SplAstNode { public: IntLiteral(int value) : value(value) {} virtual string getType() const { return "int"; } virtual void print() const { cout << value; } private: int value; }; // 变量节点类 class Variable : public SplAstNode { public: Variable(const string& name) : name(name) {} virtual string getType() const { return "variable"; } virtual void print() const { cout << name; } private: string name; }; // 表达式节点类 class Expression : public SplAstNode { public: virtual string getType() const { return "expression"; } virtual void print() const { for (auto child : children) { child->print(); cout << " "; } } void addChild(SplAstNode* child) { children.push_back(child); } private: vector<SplAstNode*> children; }; // 二元运算表达式节点类 class BinaryExpression : public Expression { public: BinaryExpression(const string& op) : op(op) {} virtual string getType() const { return "binary_expression"; } virtual void print() const { children[0]->print(); cout << " " << op << " "; children[1]->print(); } private: string op; }; // 声明语句节点类 class DeclarationStatement : public SplAstNode { public: DeclarationStatement(const string& type, const string& name) : type(type), name(name) {} virtual string getType() const { return "declaration_statement"; } virtual void print() const { cout << type << " "; cout << name; } private: string type; string name; }; // SPL 抽象语法树类 class SplAst { public: SplAst(SplAstNode* root) : root(root) {} ~SplAst() { delete root; } void print() const { root->print(); } private: SplAstNode* root; }; int main() { // 构造一个抽象语法树 BinaryExpression* expr = new BinaryExpression("+"); expr->addChild(new IntLiteral(1)); expr->addChild(new IntLiteral(2)); DeclarationStatement* decl = new DeclarationStatement("int", "x"); Expression* assign_expr = new Expression(); assign_expr->addChild(new Variable("x")); assign_expr->addChild(expr); SplAstNode* root = new Expression(); root->addChild(decl); root->addChild(assign_expr); SplAst ast(root); // 输出语法树 ast.print(); cout << endl; return 0; } ``` 这只是一个简单的实现实际的 SPL 抽象语法树可能要更复杂,具体的实现方式也会因实际需求而异。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值