黑马程序员_银行调度系统

来源:互联网 发布:c语言复合语句 编辑:程序博客网 时间:2024/05/17 02:16
----------------------ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------

项目需求

银行内有6个业务窗口,1 - 4号窗口为普通窗口,5号窗口为快速窗口,6号窗口为VIP窗口。

有三种对应类型的客户:VIP客户,普通客户,快速客户(办理如交水电费、电话费之类业务的客户)。

异步随机生成各种类型的客户,生成各类型用户的概率比例为:

        VIP客户 :普通客户 :快速客户  =  1 3

客户办理业务所需时间有最大值和最小值,在该范围内随机设定每个VIP客户以及普通客户办理业务所需的时间,快速客户办理业务所需时间为最小值(提示:办理业务的过程可通过线程Sleep的方式模拟)。

各类型客户在其对应窗口按顺序依次办理业务。 

当VIP6号)窗口和快速业务(5号)窗口没有客户等待办理业务的时候,这两个窗口可以处理普通客户的业务,而一旦有对应的客户等待办理业务的时候,则优先处理对应客户的业务。

随机生成客户时间间隔以及业务办理时间最大值和最小值自定,可以设置。

不要求实现GUI,只考虑系统逻辑实现,可通过Log方式展现程序运行结果。

2.项目设计:
1)要有一个号码管理器对象,让这个对象不断地产生号码,就等于随机生成了客户。由于有三类客户,每类客户的号码编排都是完全独立的,所以,本系统一共要产生三个号码管理器对象。NumberManager : generateNumber() , fetchNumber() ;
2)这三个号码管理器对象统一由一个号码机器进行管理,这个号码机器在整个系统中始终只能有一个,所以它要设计成单例模式。NumberMachine : getCommonManager() , getVipManager() , getExpressManager() , getInstance() ;
3)服务窗口每次找号码管理器获取当前要被服务的客户号码。ServiceWindow : start(), commonService(), expressService(), vipService() .

代码如下:

NumberManager 类:

package com.itheima;    import java.util.ArrayList;  import java.util.List;  /**  * 号码生成器每生成一个号码就代表一个客户。内部定义了一个容器,用来存储客户号码。  * 定义了两个方法,一个是产生新号码的方法,一个是获取马上要被服务的客户号码。  * 因为两个方法会被多个线程调用,会涉及到共同数据,所以要加同步锁。  */  public class NumberManager {      List<Integer> contains = new ArrayList<Integer>();            private Integer lastNumber = 1;      /*产生新号码,存储在容器内。*/      public synchronized Integer generateNewNumber(){          contains.add(lastNumber);          return lastNumber++;      }      /*获取马上被服务的号码,因为要调用remove方法,需要判断容器中是否有元素,如果容器为null,则返回null*/      public synchronized Integer gainServiceNumber(){          Integer number = null;          if(contains.size()>0)              number = contains.remove(0);          return number;      }  }  
NumberMachine类:
package com.itheima;    /**  * 号码管理器在程序运行期间只有一个对象,因此设计成单例。  * 有三个生成不同号码产生器(NumberManager)的方法,分别是commonNumberManager,  * expressNumberManager,vipNumberManager。  */  public class NumberMachine {      /*定义三种客户类型的NumberManager对象*/      private NumberManager commonNumberManager = new NumberManager();      private NumberManager expressNumberManager = new NumberManager();      private NumberManager vipNumberManager = new NumberManager();            public NumberManager getCommonNumberManager() {          return commonNumberManager;      }      public NumberManager getExpressNumberManager() {          return expressNumberManager;      }      public NumberManager getVipNumberManager() {          return vipNumberManager;      }      /*设置单例*/      private NumberMachine(){}      private static NumberMachine instance = new NumberMachine();      /*获取NumberMachine对象的静态方法*/      public static NumberMachine getInstance(){          return instance;      }  }  
ServiceWindow类:

package com.itheima;    import java.util.Random;  import java.util.concurrent.Executors;    /**  * ServerWindow可被调用的只有start方法。start方法内部根据不同的CustomerType对应了3种方法。  * 分别是commonService,expressService,vipService,为不同客户做出不同服务。  * 因此又定义了一个枚举类CustomerType,用来描述不同客户。  */  public class ServiceWindow {      /*定义客户类型属性,默认为COMMON*/      private CustomerType type = CustomerType.COMMON;      /*定义服务窗口编号*/      private int windowId;      /*窗口编号的set方法*/      public void setWindowId(int windowId) {          this.windowId = windowId;      }            ServiceWindow(CustomerType type){          this.type = type;      }      /*对外只提供start方法*/      public void start(){          /*创建一个线程,根据不同type,执行不同方法*/          Executors.newSingleThreadExecutor().execute(new Runnable(){              public void run(){                  while(true){                      /*判断type类型,执行对应的方法*/                      switch(type){                      case COMMON:                          commonService();                          break;                      case EXPRESS:                          expressService();                          break;                      case VIP:                          vipService();                          break;                      }                  }              }          });      }      /*普通客户服务方法*/      private void commonService() {          /*获取服务号码*/          Integer number = NumberMachine.getInstance().getCommonNumberManager().gainServiceNumber();          /*窗口名称*/          String windowName = "第"+windowId+"号"+type+"窗口";          System.out.println(windowName + "正在获取"+"普通"+"客户服务");          /*判断number是否为null,如果不是null,则提供服务*/          if(number!=null){              System.out.println(windowName + "开始为第" + number + "号" + "普通" + "客户服务");              /*获取随机的最大范围:最大服务时间减去最小服务时间*/              int maxRandom = Contants.MAX_SERVICE_TIME-Contants.MIN_SERVICE_TIME;              /*随机服务时间等于随机范围内的随机值加上最小服务时间*/              int serverTime = new Random().nextInt(maxRandom)+1+Contants.MIN_SERVICE_TIME;              try {                      Thread.sleep(serverTime);                  } catch (InterruptedException e) {                      e.printStackTrace();                  }              System.out.println(windowName + "为第" + number + "号" + "普通" + "客户完成服务,共耗时" + serverTime/1000 + "秒");          }          /*如果number为null,先空闲1秒*/          else{              System.out.println(windowName + "没有取到服务,先休息1秒");              try {                  Thread.sleep(1000);              } catch (InterruptedException e) {                  e.printStackTrace();              }          }      }      /*快速客服服务方法*/      private void expressService() {          Integer number = NumberMachine.getInstance().getExpressNumberManager().gainServiceNumber();          String windowName = "第"+windowId+"号"+type+"窗口";          System.out.println(windowName + "正在获取"+type+"客户服务");          if(number!=null){              System.out.println(windowName + "开始为第" + number + "号" + type + "客户服务");              /*服务时间为最小值*/              int serverTime = Contants.MIN_SERVICE_TIME;              try {                      Thread.sleep(serverTime);                  } catch (InterruptedException e) {                      e.printStackTrace();                  }              System.out.println(windowName + "为第" + number + "号" + type + "客户完成服务,共耗时" + serverTime/1000 + "秒");          }          else{              System.out.println(windowName + "没有取到服务,开始获取普通服务");              /*没有取到本类服务,再获取普通客户服务*/              commonService();          }      }      /*vip客户服务方法*/      private void vipService() {          Integer number = NumberMachine.getInstance().getVipNumberManager().gainServiceNumber();          String windowName = "第"+windowId+"号"+type+"窗口";          System.out.println(windowName + "正在获取"+type+"客户服务");          if(number!=null){              System.out.println(windowName + "开始为第" + number + "号" + type + "客户服务");              int maxRandom = Contants.MAX_SERVICE_TIME-Contants.MIN_SERVICE_TIME;              /*服务时间和普通客户相同*/              int serverTime = new Random().nextInt(maxRandom)+1+Contants.MIN_SERVICE_TIME;              try {                      Thread.sleep(serverTime);                  } catch (InterruptedException e) {                      e.printStackTrace();                  }              System.out.println(windowName + "为第" + number + "号" + type + "客户完成服务,共耗时" + serverTime/1000 + "秒");          }          else{              System.out.println(windowName + "没有取到服务,开始获取普通服务");              /*没有本类服务,也执行普通客户服务*/              commonService();          }      }  }  
CustomerType类:
package com.itheima;    /*定义客户类型枚举类*/  public enum CustomerType {      COMMON,EXPRESS,VIP;            /*重写toString方法 打印成中文*/      public String toString(){          switch(this){//this代表枚举对象          case COMMON:              return "普通";          case EXPRESS:              return "快速";          case VIP:              return name();          }          return null;      }  }  
Contants类:

package com.itheima;    /*常量类*/  public class Contants {      /*最大服务时间*/      public static int MAX_SERVICE_TIME = 10000;      /*最小服务时间*/      public static int MIN_SERVICE_TIME = 1000;      /*普通客户生成间隔时间*/      public static int COMMON_CUSTOMER_INTERVAL_TIME = 1;  }  
MainClass类:

package com.itheima;    import java.util.concurrent.Executors;  import java.util.concurrent.TimeUnit;    public class MainClass {        /**      * MainClass先创建4个普通窗口,1个快速窗口,1个vip窗口。      * 然后启动三个不同的定时器分别产生三种客户类型的号码。      * 生成各类型客户的概率比例为:vip客户 :快速客户 :普通客户 = 1:3:6.      */      public static void main(String[] args) {          /*for循环创建4个普通窗口*/          for(int i=1;i<5;i++){              ServiceWindow common = new ServiceWindow(CustomerType.COMMON);              common.setWindowId(i);              common.start();          }          /*创建1个快速窗口*/          ServiceWindow express = new ServiceWindow(CustomerType.EXPRESS);          express.setWindowId(1);          express.start();          /*创建1个vip窗口*/          ServiceWindow vip = new ServiceWindow(CustomerType.VIP);          vip.setWindowId(1);          vip.start();          /*生成普通客户号码*/          Executors.newScheduledThreadPool(1).scheduleAtFixedRate(                  new Runnable(){                      public void run(){                          int number = NumberMachine.getInstance().getCommonNumberManager().generateNewNumber();                          System.out.println("第" + number + "号" + "普通" + "客户等待服务");                      }                  },                  0,                  Contants.COMMON_CUSTOMER_INTERVAL_TIME,//以普通客户号码产生间隔时间为基数,并设置成常量。                  TimeUnit.SECONDS              );          /*产生快速客户号码*/          Executors.newScheduledThreadPool(1).scheduleAtFixedRate(                  new Runnable(){                      public void run(){                          int number = NumberMachine.getInstance().getExpressNumberManager().generateNewNumber();                          System.out.println("第" + number + "号" + "快速" + "客户等待服务");                      }                  },                  0,                  Contants.COMMON_CUSTOMER_INTERVAL_TIME * 2,//快速客户号码间隔时间为普通客户的2倍                  TimeUnit.SECONDS          );          /*产生vip客户号码*/          Executors.newScheduledThreadPool(1).scheduleAtFixedRate(                  new Runnable(){                      public void run(){                          int number = NumberMachine.getInstance().getVipNumberManager().generateNewNumber();                          System.out.println("第" + number + "号" + "VIP" + "客户等待服务");                      }                  },                  0,                  Contants.COMMON_CUSTOMER_INTERVAL_TIME * 6,//vip客户号码间隔为普通客户的6倍                  TimeUnit.SECONDS          );      }    }  






---------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------
原创粉丝点击