黑马程序员之银行业务调度系统

来源:互联网 发布:杨幂和唐嫣友情知乎 编辑:程序博客网 时间:2024/05/26 09:56

------- android培训、java培训、期待与您交流! ----------

银行业务调度系统的总结
1,对象有客户、号码、业务窗口
2,客户是根据号码来区分的,一个客户对应一个号码。号码有贵宾、普通和快速三种区分。所以要产生三个号码管理器对象,各自管理一类用户的排队号码。这三个号码管理器对象统一由一个号码机器进行管理,这个号码机器在整个系统中始终只能有一个,所以,它要被设计成单例
3,业务窗口也是根据号码的三种区分,进行不同的服务。窗口分贵宾、普通和快速三种。不同的窗口分别为不同的客户服务。所以服务窗口类需要有窗口类别的属性,另外要有窗口的名称的属性。
4,业务窗口服务不断获取客户号码,一旦有客户等待,就获取到号码进行服务。
5,在主程序中,建立窗口的实例对象,调用start方法,启动线程服务,并产生客户。
6,整个系统就是由6个线程交替执行,即贵宾(1个)、普通(4个)和快速(1个)。
7,系统用到枚举类,如果想要输出自定义的信息,需要覆盖toString方法。
8,用到一个存放常量的类。编程过程中,使用到的常量最好统一进行定义为一个类中的静态常量。
根据"谁拥有数据,谁提供处理数据的方法"的原则进行分析
   客户拥有贵宾、普通、快速三种特性,所以客户应该提供生成三种客户的方法。但是客户其实是跟号码一一对应的,银行是根据号码来确定有没有客户的。所以提供生成三种客户方法的对象应该是号码。
   号码还要提供获取下一个要服务的对象的方法和产生新号码的方法。
   窗口拥有窗口ID、窗口类别(贵宾、普通和快速)的属性,还要有为客户服务的方法。
程序处理流程
   1,main方法中,创建三种类型服务窗口的对象,并调用对象的start方法,启动线程。
   2,每个对象启动一个线程。线程中根据对象的类别(Type)不同,进行不同的服务(commonServie,vipService,expressService)。
   3,普通客户服务(commonService)流程:
      首先利用号码机获得普通客户的实例对象,然后调用号码管理类的fetchServiceNumber方法获取一个普通客户队列等待服务的号码。如果号码不为空,则开始服务,否则等待。
   4,快速客户服务(expressService)流程:
      首先利用号码机获得快速客户的实例对象,然后调用号码管理类的fetchServiceNumber方法获取一个快速客户队列等待服务的号码。如果号码不为空,则开始服务,否则进行普通客户服务。
   5,VIP客户服务(vipService)流程:
      首先利用号码机获得VIP客户的实例对象,然后调用号码管理类的fetchServiceNumber方法获取一个VIP客户队列等待服务的号码。如果号码不为空,则开始服务,否则进行普通客户服务。

源代码:

号码管理类:

package bank;import java.util.ArrayList;import java.util.List;public class NumberManager {private int lastNumber = 1;//变量的类型尽量用超类private List<Integer> queueNumber = new ArrayList<Integer>();//多个线程访问同一个数据的时候,要互斥public synchronized Integer generateNewManager(){queueNumber.add(lastNumber);return lastNumber++;}public synchronized  Integer fetchServiceNumber(){Integer number = null;//队列有值才取号,否则报错if(queueNumber.size()>0){number = queueNumber.remove(0);}//取走集合中的值,这个方法有一个返回值,返回值就是取走的值return number;}}

 

号码机:
 

package bank;public class NumberMachine {private NumberManager commonManager = new NumberManager();private NumberManager expressManager = new NumberManager();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(){return instance;}private static NumberMachine instance = new NumberMachine();}

 

业务窗口:
 

package bank;import java.util.Random;import java.util.concurrent.Executors;public class ServiceWindow {//使用set和get方法设置属性值,比较灵活;如果使用构造方法生成时赋值,那么不能进行改动public void setType(CustomerType type) {this.type = type;}public void setWindowId(int windowId) {this.windowId = windowId;}//默认是普通窗口private CustomerType type = CustomerType.COMMON;private int windowId = 1;public void start(){//线程池执行任务,线程池在到池里去找一个空闲的线程去执行Executors.newSingleThreadExecutor().execute(new Runnable(){public void run() {while(true){//switch效率比if else高,switch的数据类型不能是longswitch(type){case COMMON:commonService();break;case VIP:vipService();break;case EXPRESS:expressService();break;}//NumberMachine.getInstance();}}});}private void commonService() {String windowName = "第"+windowId+"号"+type+"窗口";Integer number = NumberMachine.getInstance().getCommonManager().fetchServiceNumber();System.out.println(windowName+"正在获取需要服务的号码");if(number!=null){System.out.println(windowName+"为第"+number+"个"+"普通"+"客户服务");//开始服务的时间long beginTime = System.currentTimeMillis();//最大的服务时间int maxRand = Constants.MAX_SERVICE_TIME-Constants.MIN_SERVICE_TIME;//随机的服务时间,产生的随机数位0到8999之间的随机数,希望产生1-9000,所以再加1long serviceTime=new Random().nextInt(maxRand)+1+Constants.MIN_SERVICE_TIME;try {Thread.sleep(serviceTime);} catch (InterruptedException e) {e.printStackTrace();}//服务结束的时间long endTime = System.currentTimeMillis();//服务耗时long costTime = endTime-beginTime;System.out.println(windowName+"为第"+number+"个"+type+"客户完成服务,同时消耗时间为"+costTime);}else{System.out.println(windowName+"没有需要服务的号码,先休息一秒");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) {e.printStackTrace();}long endTime = System.currentTimeMillis();long costTime = endTime-beginTime;System.out.println(windowName+"为第"+number+"个"+type+"客户完成服务,同时消耗时间为"+costTime);}else{System.out.println(windowName+"没有需要服务的号码,先休息一秒");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;//随机的服务时间,产生的随机数位0到8999之间的随机数,希望产生1-9000,所以再加1long serviceTime=new Random().nextInt(maxRand)+1+Constants.MIN_SERVICE_TIME;try {Thread.sleep(serviceTime);} catch (InterruptedException e) {e.printStackTrace();}long endTime = System.currentTimeMillis();long costTime = endTime-beginTime;System.out.println(windowName+"为第"+number+"个"+type+"客户完成服务,同时消耗时间为"+costTime);}else{System.out.println(windowName+"没有需要服务的号码,开始获取普通用户");commonService();}}}

 

客户类型,即号码类型:使用枚举
 

package bank;public enum CustomerType {COMMON,VIP,EXPRESS;//typepublic String toString(){switch(this){case COMMON:return "普通";case VIP:return "贵宾";case EXPRESS:return "快速";}return null;}}


 常量类:最大服务时间,最小服务时间,客户进来的频率

 

package bank;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;}

 

主程序:
 

package bank;import java.util.concurrent.Executors;import java.util.concurrent.TimeUnit;public class mainClass {/** * @param args */public static void main(String[] args) {//4个普通窗口for(int i = 1;i<5;i++){ServiceWindow commonWindow = new ServiceWindow();commonWindow.setWindowId(i);commonWindow.start();}//贵宾窗口ServiceWindow vipWindow = new ServiceWindow();vipWindow.setType(CustomerType.VIP);vipWindow.start();//快速窗口ServiceWindow expressWindow = new ServiceWindow();expressWindow.setType(CustomerType.EXPRESS);expressWindow.start();//COMMON调度线程池,一秒钟增加一个普通客户Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable(){public void run() {Integer number = NumberMachine.getInstance().getCommonManager().generateNewManager();System.out.println(number + "号普通客户等待服务!");}}, 0, Constants.COMMON_CUSTOMER_INTERVAL_TIME, TimeUnit.SECONDS);//vipExecutors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable(){public void run() {Integer number = NumberMachine.getInstance().getVipManager().generateNewManager();System.out.println(number + "号VIP客户等待服务!");}}, 0, Constants.COMMON_CUSTOMER_INTERVAL_TIME * 6, TimeUnit.SECONDS);//EXPRESSExecutors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable(){public void run() {Integer number = NumberMachine.getInstance().getExpressManager().generateNewManager();System.out.println(number + "号快速客户等待服务!");}}, 0, Constants.COMMON_CUSTOMER_INTERVAL_TIME * 2, TimeUnit.SECONDS);}}



 

原创粉丝点击