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

xiaoxiao2021-02-28  107

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

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

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

                     涉及的动作有:

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

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

问题抽象:

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

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

这两个线程需要同步执行,即当我们的存钱线程在进行时(存钱线程被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);     } }
转载请注明原文地址: https://www.6miu.com/read-22962.html

最新回复(0)