银行业务调度系统学习笔记


    模拟实现银行业务调度系统逻辑,具体需求如下:  
      
    >   银行内有6个业务窗口,1 - 4号窗口为普通窗口,5号窗口为快速窗口,6号窗口为VIP窗口。  
      
    >  有三种对应类型的客户:VIP客户,普通客户,快速客户(办理如交水电费、电话费之类业务的客户)。  
      
    >  异步随机生成各种类型的客户,生成各类型用户的概率比例为:  
      
            VIP客户 :普通客户 :快速客户  =  1 :6 :3。  
      
    >  客户办理业务所需时间有最大值和最小值,在该范围内随机设定每个VIP客户以及普通客户办理业务所需的时间,快速客户办理业务所需时间为最小值(提示:办理业务的过程可通过线程Sleep的方式模拟)。  
      
    >  各类型客户在其对应窗口按顺序依次办理业务。   
      
    >  当VIP(6号)窗口和快速业务(5号)窗口没有客户等待办理业务的时候,这两个窗口可以处理普通客户的业务,而一旦有对应的客户等待办理业务的时候,则优先处理对应客户的业务。  
      
    >  随机生成客户时间间隔以及业务办理时间最大值和最小值自定,可以设置。  
      
    >  不要求实现GUI,只考虑系统逻辑实现,可通过Log方式展现程序运行结果。  


根据以上需求,我们可以整理出以下思路

    /* 
             * 思路分析: 
             * 1.客户进来取号     比例 
             *   1>VIP客户取号    1 
             *   2>快速客户取号   3 
             *   3>普通客户取号   6 
             *  
             * 2.机器存储已经产生的号码 
             *  
             * 3.服务窗口开始叫号 
             *   1>.VIP服务窗口获取VIP客户 
             *       >.为空:VIP窗口获取普通客户 
             *           >.为空:休息一秒 
             *           >.不为空:VIP窗口为普通客户服务,服务时间2秒 
             *       >.不为空:VIP窗口为VIP客户服务,服务时间3秒 
             *   2>.快速服务窗口获取快速客户 
             *       >.为空:快速服务窗口获取普通客户 
             *           >.为空:休息一秒 
             *           >.不为空:快速服务窗口为普通客户服务,服务时间2秒 
             *       >.不为空:快速服务窗口为快速客户服务,服务时间1秒 
             *   3>.普通服务窗口获取普通客户 
             *       >为空:休息一秒 
             *       >不为空:普通服务窗口为普通客户服务,服务时间2秒 
             * 面向对象建模: 
             * 1.号码机器类 
             * 2.号码管理类 
             * 3.服务窗口类       
             * 4.用户类别枚举类 
             * */  


整理出以上需求后,再按照思路一步步的写代码,就简单多了

    /** 
     * 号码机器类:负责产生用户的取号和存储客户取过后的号码 
     * 号码机器类提供如下方法: 
     * 1.获取客户号码的方法getCustomerNumber(),每进来一个客户就调用该方法取一个号 
     * 2.窗口叫号的方法:getServiceNumber(),该方法告诉窗口下一个需要服务的客户号码 
     * 注意:由于多个用户可能同时取号,多个窗口也可能同时为客户服务,所以这两个方法涉及到多线程 
     * 操作共享数据的问题,需要加同步代码块 
     * */  
    public class NumberMachine {  
      
        //号码队列存储器  
        private List queue = new LinkedList();  
        //号码计数器  
        private Integer lastNumber=1;  
          
        //客户取号,该方法涉及到多个客户可能同时取号的情况,所以需要加同步  
        public synchronized Integer getCustomerNumber(){  
            queue.add(lastNumber);  
            return lastNumber++;  
        }  
          
        //窗口取号,该方法涉及到多个服务窗口可能同时取号的情况,所以需要加同步  
        public synchronized Integer getServiceNumber(){  
            if(queue != null && queue.size()>0){  
                return queue.remove(0);  
            }  
            return null;  
        }  
          
    }  


    /** 
     * 号码管理类:负责管理所有的号码,利用单例模式对外只提供一个实例, 
     * 为不同的客户提供操作号码机器的对象,以便客户获取号码 
     * */  
    public class NumberManager {  
      
        private NumberManager(){  
              
        }  
        private NumberMachine commonManager = new NumberMachine();  
        private NumberMachine expressManager = new NumberMachine();  
        private NumberMachine vipManager = new NumberMachine();  
      
        //为普通客户提供操作机器对象的实例  
        public NumberMachine getCommonManager() {  
            return commonManager;  
        }  
        //为快速客户提供操作机器对象的实例  
        public NumberMachine getExpressManager() {  
            return expressManager;  
        }  
        //为VIP客户提供操作机器对象的实例  
        public NumberMachine getVipManager() {  
            return vipManager;  
        }  
          
        public static NumberManager getInstance(){  
            return instance;  
        }  
        private static NumberManager instance = new NumberManager();  
    }  


    /** 
     * 客户类别枚举类:维护客户类别 
     * */  
    public enum CustomerType {  
        COMMON,EXPRESS,VIP;  
        //重写本类的toString方法,获取转换后的字符串  
        public String toString(){  
            switch(this){  
                case COMMON:  
                    return "普通客户";  
                case EXPRESS:  
                    return "快速客户";  
                case VIP:  
                    //return name()返回的就是VIP  
                    return name();  
            }  
            return null;  
        }  
    }  


    public class Constant {  
        //最大服务时间  
        public static final long MAX_SERVICE_TIME = 3000;  
        //最短服务时间  
        public static final long MIN_SERVICE_TIME = 1000;  
        //客户取号时间间隔  
        public static final long COMMON_CUSTOMER_INTERVAL_TIME  = 1;  
        //普通客户未取到号后的休息时间  
        public static final long COMMON_CUSTOMER_GETNONUMBER = 1000;  
    }  


    /** 
     * 窗口类:用于服务不同的客户根据不同的客户,调用不同的客服服务方法 
     * */  
    public class ServiceWindow {  
      
        //窗口号  
        private int windowId;  
        //客户类别,此处用作窗口类别  
        private CustomerType type = CustomerType.COMMON;  
      
        public ServiceWindow(int windowId, CustomerType customerType) {  
            this.windowId = windowId;  
            this.type = customerType;  
        }  
      
        //开始服务  
        public void startService() {  
            Executors.newFixedThreadPool(1).execute(new Runnable() {  
                public void run() {  
                    while(true){  
                        switch (type) {  
                            case COMMON:  
                                type = CustomerType.COMMON;  
                                commonService();  
                                break;  
                            case EXPRESS:  
                                type = CustomerType.EXPRESS;  
                                expressService();  
                                break;  
                            case VIP:  
                                type = CustomerType.VIP;  
                                vipService();  
                                break;  
                        }  
                    }  
                }  
            });  
        }  
      
        // 为普通客户服务方法  
        private void commonService() {  
            Integer number = NumberManager.getInstance().getCommonManager()  
            .getServiceNumber();  
            customerService(CustomerType.COMMON, number);  
        }  
      
        private void customerService(CustomerType ctype, Integer number) {  
            System.out.println(this.windowId + " 号 " + type + " 窗口开始为"+ctype+"服务");  
            if (number == null) {  
                System.out.println(this.windowId + " 号 " + type + " 窗口没有取到号");  
                if(ctype==CustomerType.COMMON){  
                    haveAnRest();  
                }else{  
                    //为普通客户服务  
                    commonService();  
                }  
            } else {  
                System.out.println(this.windowId + " 号 " + type + " 窗口正在为 "  
                        + number + " 号"+ctype+"服务");  
                // 获取生成服务时间的区间  
                long serviceTime = getServiceTimeByType(ctype);  
                try {  
                    Thread.sleep(serviceTime);  
                } catch (InterruptedException e) {  
                    e.printStackTrace();  
                }  
            }  
        }  
      
        // 为快速客户服务方法  
        private void expressService() {  
            Integer number = NumberManager.getInstance().getExpressManager()  
            .getServiceNumber();  
            customerService(CustomerType.EXPRESS, number);  
        }  
      
        // 为VIP客户服务方法  
        private void vipService() {  
            Integer number = NumberManager.getInstance().getVipManager()  
            .getServiceNumber();  
            customerService(CustomerType.VIP, number);  
        }  
          
        //暂停取号  
        private void haveAnRest() {  
            try {  
                Thread.sleep(Constant.COMMON_CUSTOMER_GETNONUMBER);  
            } catch (InterruptedException e) {  
                e.printStackTrace();  
            }  
        }  
          
        //根据客户类型获取服务时间  
        private long getServiceTimeByType(CustomerType ctype) {  
            if(ctype == CustomerType.EXPRESS)  
                return Constant.MIN_SERVICE_TIME;  
            long intervalTime = Constant.MAX_SERVICE_TIME  
                    - Constant.MIN_SERVICE_TIME;  
            long serviceTime = (new Random().nextInt((int) intervalTime) + 1)  
                    + Constant.MIN_SERVICE_TIME;  
            return serviceTime;  
        }  
    }  


    public class MainClass {  
      
        /** 
         * @param args 
         */  
        public static void main(String[] args) {  
            /* 
             * 思路分析: 
             * 1.客户进来取号     比例 
             *   1>VIP客户取号    1 
             *   2>快速客户取号   3 
             *   3>普通客户取号   6 
             *  
             * 2.机器存储已经产生的号码 
             *  
             * 3.服务窗口开始叫号 
             *   1>.VIP服务窗口获取VIP客户 
             *       >.为空:VIP窗口获取普通客户 
             *           >.为空:休息一秒 
             *           >.不为空:VIP窗口为普通客户服务,服务时间2秒 
             *       >.不为空:VIP窗口为VIP客户服务,服务时间3秒 
             *   2>.快速服务窗口获取快速客户 
             *       >.为空:快速服务窗口获取普通客户 
             *           >.为空:休息一秒 
             *           >.不为空:快速服务窗口为普通客户服务,服务时间2秒 
             *       >.不为空:快速服务窗口为快速客户服务,服务时间1秒 
             *   3>.普通服务窗口获取普通客户 
             *       >为空:休息一秒 
             *       >不为空:普通服务窗口为普通客户服务,服务时间2秒 
             * 面向对象建模: 
             * 1.号码机器类 
             * 2.号码管理类 
             * 3.服务窗口类       
             * 4.用户类别枚举类 
             * */  
            //开启四个普通客户服务窗口  
            for(int i=1; i<=4; i++){  
                ServiceWindow commonWindow = new ServiceWindow(i,CustomerType.COMMON);  
                commonWindow.startService();  
            }  
            //开启快速客户服务窗口  
            ServiceWindow expressWindow = new ServiceWindow(1,CustomerType.EXPRESS);  
            expressWindow.startService();  
            //开启VIP客户服务窗口  
            ServiceWindow vipWindow = new ServiceWindow(1,CustomerType.VIP);  
            vipWindow.startService();  
              
            //普通客户开始取号  
            Executors.newScheduledThreadPool(1).scheduleAtFixedRate(  
                    new Runnable(){  
                        public void run(){  
                            Integer number = NumberManager.getInstance().getCommonManager().getCustomerNumber();  
                            System.out.println(number+" 号普通客户正在等待服务...");  
                        }  
                    },   
                    1,   
                    Constant.COMMON_CUSTOMER_INTERVAL_TIME,   
                    TimeUnit.SECONDS);  
              
            //快速客户开始取号  
            Executors.newScheduledThreadPool(1).scheduleAtFixedRate(  
                    new Runnable(){  
                        public void run(){  
                            Integer number = NumberManager.getInstance().getExpressManager().getCustomerNumber();  
                            System.out.println(number+" 号快速客户正在等待服务...");  
                        }  
                    },   
                    1,   
                    Constant.COMMON_CUSTOMER_INTERVAL_TIME * 3,   
                    TimeUnit.SECONDS);  
              
            //VIP客户开始取号  
            Executors.newScheduledThreadPool(1).scheduleAtFixedRate(  
                    new Runnable(){  
                        public void run(){  
                            Integer number = NumberManager.getInstance().getVipManager().getCustomerNumber();  
                            System.out.println(number+" 号VIP客户正在等待服务...");  
                        }  
                    },   
                    1,   
                    Constant.COMMON_CUSTOMER_INTERVAL_TIME * 6,   
                    TimeUnit.SECONDS);  
              
        }  
    }  


你可能感兴趣的:(编程语言)