银行业务调度系统

    技术2025-10-12  7

    1.       银行业务系统的面向对象分析

    1)  有三种对应类型的客户:VIP客户、普通用户、快速客户,异步随机产生各种客户(号码),各类型客户在窗口按顺序依次办理业务

    2)  在每个窗口设置一个扫描器,对存储三种类型客户的数组进行扫描。如果存在相应客户,则取出客户,办理业务(该线程休眠)。如果VIP和快速窗口里没用客户,则去普通客户里去取。

    3)  把三种用户类型定义为枚举,他们的字符串打印为中文格式。

    4)  定义一个服务窗口(ServiceWindow),添加start方法,内部启动1个线程,根据服务窗口的类别(定义6个线程,4个普通窗口,1vip窗口,一个快速窗口),分别循环调用三个不同的方法。

    5)  打印出每个窗口在执行过程中的细节,以便于结果分析。

     

    2.       NumberManger类代码分析

    1)  定义一个用于存储一个客户号码的 成员变量和用于存储等待服务的客户号码的队列集合。

    2)  定义了一个产生新号码的方法和一个获取马上要为之服务的方法,这两个方法之间要进行线程同步。

    源代码:

    package cn.itcast.bankqueue;

     

    import java.util.*;

     

    public class NumberManager {

        //最新的排队号

        private int lastNumber=1;

        //定义一个用来存储排队号的集合

        private List<Integer> queueNumber=new ArrayList<Integer>();

        //定义一个取号的方法

        public synchronized   Integer generateNewManager()

        {

           //把获得的最新号码存到集合中

           queueNumber.add(lastNumber);

           //返回添加的号码,并让新号码+1

           return lastNumber++;

        }

        //获得集合中最靠前的号码

        public synchronized Integer fetchServiceNumber()

        {

           //如果集合的长度不为0,移除输出的第一个元素并返回

           if (queueNumber.size()!=0) {

               return queueNumber.remove(0);

           }

           //如果集合长度为0,返回空

           return null;

        }

         

    }

    3.       NumberMachine

    1)  定义三个成员变量分别指向三个NumberManager对象,分别表示普通、快速、VIP客户的号码管理器,定义三个方法来返回这三个NumberManger对象

    2)  NumberMachine设置成单例(只有一个取号器?)。

    源代码分析:

    package cn.itcast.bankqueue;

     

    public class NumberMachine {

        //设置一个普通客户管理器对象

        private NumberManager commonManager=new NumberManager();

        //设置一个快速客户管理器对象

        private NumberManager expressManager=new NumberManager();

        //设置一个vip客户管理器对象

        private NumberManager vipManager=new NumberManager();

        //用来分别返回这三个对象的方法

        public NumberManager getCommonManager() {

           return commonManager;

        }

        public NumberManager getExpressManager() {

           return expressManager;

        }

        public NumberManager getVipManager() {

           return vipManager;

        }

        //设计一个单例

        private NumberMachine(){}

        public static NumberMachine getInstance()

        {

           //NumberMachine instance=new NumberMachine();

           return instance;

        }

        private static NumberMachine instance=new NumberMachine();

    }

    思考:单例的方法和成员都是静态的。是否可以在方法内定义对象。

    4.       CustomerType枚举类和Constant

    1)  系统中有三种类型的客户,所以定义一个枚举类,其中三个成员分别表示三种类型的客户。

    2)  重写toString方法,返回类型的中文名称。

    源代码分析:

    package cn.itcast.bankqueue;

     

    public enum CustomerType {

        //定义三种类型的客户

        COMMON,EXPRESS,VIP;

        //重写toString方法

        public String toString()

        {

           switch (this) {

           case COMMON:

               return "普通";

           case EXPRESS:

               return "快速";

           case VIP:

               return name();

           }

           return null;

        }

    }

     

    1)    Contants类定义三个常量:MAX_SERVICE_TIME(窗口最大服务时间)MIN_SERVICE_TIME(窗口最大服务时间)COMMON_CUSTOMER_INTERVAL_TIME(普通用户产生的时间间隔)

    package cn.itcast.bankqueue;

     

    public class Constants {

        //服务最大时间

        public static int MAX_SERVICE_TIME=10000;

        //服务最小时间

        public static int MIN_SERVICE_TIME=1000;

        //普通用户到来的时间间隔

        public static int COMMON_CUSTOMER_INTERVAL_TIME=1;

    }

    5.    ServiceWindow

    1)    定义一个start方法,内部启动一个线程,根据服务窗口的类别分别循环调用三个不同德方法。

    2)    定义三个方法分别对三类客户进行服务,为了观察运行效果打印出详细信息。

    源代码分析:

    package cn.itcast.bankqueue;

     

    import java.util.Random;

    import java.util.concurrent.Executors;

     

    public class ServiceWindow {

        //设置用户类型的属性

        private CustomerType type=CustomerType.COMMON;

        //设置装口编码的属性

        private int windowId=1; 

        public void setType(CustomerType type) {

           this.type = type;

        }

        public void setWindowId(int windowId) {

           this.windowId = windowId;

        }

        //编写start方法

        public void start()

        {

           //开启一个新的线程

           Executors.newSingleThreadExecutor().execute(new Runnable(){

     

               public void run() {

                  //根据不同的客户类型选择不同的执行方法

                  while (true) {

                      switch (type) {

                      case COMMON:

                      commonService();

                      break;

                      case EXPRESS:

                       expressService();

                      break;

                      case VIP:

                      VIPService();

                      break;

                  }

                  }

                  }  

                  });

        }

    //普通用户服务方法

    private void commonService()  {

        //窗口服务信息字符串

        String windowName=""+windowId+""+type+"窗口";

        //去普通用户的队列里查找最靠前的用户并返回用户号码。

    Integer number= NumberMachine.getInstance().getCommonManager().fetchServiceNumber();

    //提示xx窗口开始获取服务

    System.out.println(windowName+"正在获取任务...");

    //如果普通用户队列里取出了用户,则进入if语句

    if (number!=null) {

        //提示xx窗口为xx客户服务

        System.out.println(windowName+"正在为"+number+""+"普通"+"客户服务!");

        //服务开始时间

        long beginTime=System.currentTimeMillis();

        //产生随机数范围(9000

        int maxRand=Constants.MAX_SERVICE_TIME-Constants.MIN_SERVICE_TIME;

        //产生随机服务时间(1-10s

        long serveTime=new Random().nextInt(maxRand)+1+Constants.MIN_SERVICE_TIME;

        try {

           //开始为用户服务(该线程开始休眠)

           Thread.sleep(serveTime);

        } catch (InterruptedException e) {

           e.printStackTrace();

        }

        //获得该次服务耗费的时间

        long costTime=System.currentTimeMillis()-beginTime;

        //打印服务信息

        System.out.println(windowName+"为第"+number+""+"普通"+"客户完成服务!:耗时"+costTime/1000+"");

    } else {

        //如果队列中没有客户则该银行职员休息1

        System.out.println(windowName+"没有取到任务,先休息1秒钟");

        try {

           //银行职员开始休息

           Thread.sleep(1000);

        } catch (InterruptedException e) {

           e.printStackTrace();

        }

       

    }

    }

    //快速用户服务方法

    private void expressService()  {

        String windowName=""+windowId+""+type+"窗口";

        Integer number= NumberMachine.getInstance().getExpressManager().fetchServiceNumber();

        System.out.println(windowName+"正在获取任务...");

    if (number!=null) {

        System.out.println(windowName+"正在为"+number+""+type+"客户服务!");

        long beginTime=System.currentTimeMillis();

        try {

           Thread.sleep(Constants.MIN_SERVICE_TIME);

        } catch (InterruptedException e) {

           // TODO Auto-generated catch block

           e.printStackTrace();

        }

        long costTime=System.currentTimeMillis()-beginTime;

        System.out.println(windowName+"为第"+number+""+type+"客户完成服务!:耗时"+costTime/1000+"");

    } else {

        System.out.println(""+windowId+""+type+"窗口没有取到任务");

        //如果快速窗口没有取到快速客户,则去普通客户窗口去取

        commonService();

       

    }

    }

    //VIP用户

    private void VIPService()  {

        String windowName=""+windowId+""+type+"窗口";

    Integer number= NumberMachine.getInstance().getVipManager().fetchServiceNumber();

    System.out.println(windowName+"正在获取任务...");

    if (number!=null) {

        System.out.println(windowName+"正在为"+number+""+type+"客户服务!");

        long beginTime=System.currentTimeMillis();

        int maxRand=Constants.MAX_SERVICE_TIME-Constants.MIN_SERVICE_TIME;

        long serveTime=new Random().nextInt(maxRand)+1+Constants.MIN_SERVICE_TIME;

        try {

           Thread.sleep(serveTime);

        } catch (InterruptedException e) {

           // TODO Auto-generated catch block

           e.printStackTrace();

        }

        long costTime=System.currentTimeMillis()-beginTime;

        System.out.println(windowName+"为第"+number+""+type+"客户完成服务!:耗时"+costTime/1000+"");

    } else {

        System.out.println(""+windowId+""+type+"窗口没有取到任务");

        //如果vip窗口没有取到vip客户,则去普通客户窗口去取

        commonService();

       

    }

    }

    }

    6.       MainClass

    1)    for循环创建出4个普通窗口,再创建一个VIP窗口,一个快速窗口。

    2)    创建三个定时器,分别定时去创建普通用户、快速客户和vip客户。

    package cn.itcast.bankqueue;

     

    import java.util.concurrent.Executors;

    import java.util.concurrent.TimeUnit;

     

    public class MainClass {

     

     

        public static void main(String[] args) {

           //定义4个普通窗口

           for (int i = 1; i < 5; i++) {

               ServiceWindow  commonwindow=new ServiceWindow();

               //设置普通窗口ID

               commonwindow.setWindowId(i);

               //开启普通窗口的服务

               commonwindow.start();

           }

           //定义一个VIP窗口

           ServiceWindow  vipwindow=new ServiceWindow();

            //设置窗口的类型

           vipwindow.setType(CustomerType.VIP);

           vipwindow.start();

           //定义一个快速窗口

           ServiceWindow  expresswindow=new ServiceWindow();

           //设置窗口的类型为快速窗口

           expresswindow.setType(CustomerType.EXPRESS);

           expresswindow.start();

           //定时产生一个普通客户

           Executors.newScheduledThreadPool(1).scheduleAtFixedRate(

                  new Runnable()

                  {

     

                      public void run() {

                      //产生一个客户,并返回该客户的编号

                      Integer number=    NumberMachine.getInstance().getCommonManager().generateNewManager();

                      //显示xx号客户开始等待服务

                      System.out.println(number+"号普通客户等待服务!");

                        

                      }

                     

                  },

                  0,

                  Constants.COMMON_CUSTOMER_INTERVAL_TIME,

                  TimeUnit.SECONDS

                  );

              //vip客户

           Executors.newScheduledThreadPool(1).scheduleAtFixedRate(

                  new Runnable()

                  {

     

                      public void run() {

                         Integer number=    NumberMachine.getInstance().getVipManager().generateNewManager();

                         System.out.println(number+"VIP客户等待服务!");

                        

                      }

                     

                  },

                  0,

                  6*Constants.COMMON_CUSTOMER_INTERVAL_TIME,

                   TimeUnit.SECONDS

                  );

           //快速客户

           Executors.newScheduledThreadPool(1).scheduleAtFixedRate(

                  new Runnable()

                  {

     

                      public void run() {

                         Integer number=    NumberMachine.getInstance().getExpressManager().generateNewManager();

                         System.out.println(number+"号快速客户等待服务!");

                        

                      }

                     

                  },

                  0,

                  2*Constants.COMMON_CUSTOMER_INTERVAL_TIME,

                  TimeUnit.SECONDS

                  );

        }

     

    }

    总结;勤学多练,希望有一天我也能写出这样优秀的代码。

    最新回复(0)