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

题目:银行业务调度

需求:

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


面向对象分析所需类

去过银行办业务的人都知道:第一步,取号(有几种不同的号,本题直接简化成三种普通,快速,VIP);第二步,等待叫号;第三步,叫号办理业务。一次循环

分析所需类:叫号机(NumbleMachine),三种不同号(号码管理器(NumbleManager)),服务窗口(ServiceWindow)。


对所需类进行设计

1.号码管理器(NumbleManager)

(1)号码管理器应该有两个方法产生号码generateNewNumber()和让服务窗口知道这个号码fetchServiceNumber()

(2)具体代码

package cn.itcast.bank;     
import java.util.ArrayList;  
import java.util.List;    
public class NumberManager {  
    private int lastNumber =1;  //银行编号都从1开始   
    //肯定是产生多个客户这里的客户 简化用Integer类型来标示  
    private List<Integer> queueNumber =new ArrayList<Integer>();
    //产生新号码的方法
    public synchronized Integer generateNewNumber(){   
       queueNumber.add(lastNumber);     
       return lastNumber++;  
    }
    //告诉服务台的方法  
    public synchronized Integer fetchServiceNumber(){  
       Integer number = null;  
       if(queueNumber.size() >0){  
           return queueNumber.remove(0);   
       }  
       return number;  
    }  
}

2.叫号机(NumbleMachine)

(1)去过银行的人都知道,银行一般只有一个叫号机,因此叫号机必须是单例,可以把号码管理器作为其成员

(2)具体代码

package cn.itcast.bank;   
public class NumberMachine {   
    private NumberManager commonManager =new NumberManager(); //普通客户    
    private NumberManager expressManager =new NumberManager();  //快速客户   
    private NumberManager vipManager =new NumberManager();//VIP客户  
    //获取普通客户的号码管理器  
    public NumberManager getCommonManager() {  
       return commonManager;  
    }   
    //获取快速客户的号码管理器  
    public NumberManager getExpressManager() {  
       return expressManager;  
    }  
    //获取VIP客户的号码管理器  
    public NumberManager getVipManager() {  
       return vipManager;  
    }   
    //叫号机的单例设计 
    private NumberMachine(){}  
    private static final NumberMachine instance =new NumberMachine();    
    public static NumberMachine getInstance(){  
       return instance;  
    }  
}  


3.服务窗口(ServiceWindow)

(1)注意快速窗口和VIP窗口,没业务时要做普通窗口的业务

(2)具体代码

package cn.itcast.bank;     
import java.util.Random;  
import java.util.concurrent.Executors;  
public class ServiceWindow {  
    //窗口的性质  
    private CustomerType type = CustomerType.COMMON; //默认为普通类型的客户  
    //窗口的编号  
    private int windowId =1;    
    //窗口的type  
    public void setType(CustomerType type) {  
       this.type = type;  
    }  
    //窗口的号码
    public void setWindowId(int windowId) {  
       this.windowId = windowId;  
    }  
    //窗口进行服务的代码
    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() {  
       StringwindowName ="第"+ windowId +"号" +type+"窗口";  
       System.out.println(windowName+ "正在获取任务...");  
        //获取要服务的客户号码  
       Integer number =  
              NumberMachine.getInstance().getCommonManager().fetchServiceNumber();  
       if(number !=null){  
           System.out.println(windowName+"正在为第"+ number+"个普通客户服务...");     
           //普通客户要求服务的时间在一个范围内的随机值  
           int maxInterval =Constants.MAX_SERVICE_INTERVAL_TIME -Constants.MIN_SERVICE_INTERVAL_TIME;  
           int serviceTime =new Random().nextInt(maxInterval) +1+Constants.MIN_SERVICE_INTERVAL_TIME;  
           long beginTime =System.currentTimeMillis();  
           try {  
              //模拟服务  
              Thread.sleep(serviceTime);  
           }catch (InterruptedException e) {  
              e.printStackTrace();  
           }  
           long endTime =System.currentTimeMillis();  
           //服务完成啦  
           System.out.println(windowName +"为第"+number+"个普通客户完成服务。耗时: "+(endTime -beginTime)/1000+"s");  
       }else{  
           //没有获取到号码  
           System.out.println(windowName +"没有获取到号码,休息一秒钟。。");  
           try {  
              Thread.sleep(1000);  
           }catch (InterruptedException e) {  
              e.printStackTrace();  
           }  
       }  
    }   
    //快速窗口为快速客户服务代码   
    private void expressService() {  
       StringwindowName ="第"+ windowId +"号 "+ type+"窗口";  
       System.out.println(windowName+ "正在获取任务...");  
       Integer number=  
              NumberMachine.getInstance().getExpressManager().fetchServiceNumber();  
        
       if(number !=null){  
           System.out.println(windowName+"正在为第"+ number+"个快速客户服务...");   
           int serviceTime = Constants.MIN_SERVICE_INTERVAL_TIME;  
           long beginTime =System.currentTimeMillis();  
           try {  
              Thread.sleep(serviceTime);  
           }catch (InterruptedException e) {  
              e.printStackTrace();  
           }  
           long endTime =System.currentTimeMillis();  
           //服务完成啦  
           System.out.println(windowName +"为第"+number+"个"+ type+"客户完成服务。耗时: "+(endTime -beginTime)/1000+"s");  
       }else{  
           //没有获取到号码则为普通用户进行服务  
           System.out.println(windowName+"此时没有获取到任何"+ type+ "号码");  
           commonService();  
       }  
        
    }  
    // VIP窗口为VIP客户服务代码     
    private void vipService() {  
       StringwindowName ="第"+ windowId +"号" +type+"窗口";  
       System.out.println(windowName+ "正在获取任务...");  
       //获取要服务的客户号码  
       Integer number =  
              NumberMachine.getInstance().getVipManager().fetchServiceNumber();  
       if(number !=null){  
           System.out.println(windowName+"正在为第"+ number+"个 VIP客户服务...");    
           int maxInterval =Constants.MAX_SERVICE_INTERVAL_TIME -Constants.MIN_SERVICE_INTERVAL_TIME;  
           int serviceTime =new Random().nextInt(maxInterval) +1+Constants.MIN_SERVICE_INTERVAL_TIME;  
           long beginTime =System.currentTimeMillis();  
           try {  
              //模拟服务  
               Thread.sleep(serviceTime);  
           }catch (InterruptedException e) {  
              e.printStackTrace();  
           }  
           long endTime =System.currentTimeMillis();  
           //服务完成啦  
           System.out.println(windowName +"为第"+number+"个普通客户完成服务。耗时: "+(endTime -beginTime)/1000+"s");  
       }else{  
           //没有获取到号码则为普通用户进行服务  
           System.out.println(windowName+"此时没有获取到任何"+ type+ "号码");  
           commonService();  
       }  
    }  
}  

4.主函数(MainClass)

(1)这个主函数的开启9个线程(6个窗口,3个生成号)

(2)具体代码

package cn.itcast.bank;    
import java.util.concurrent.Executors;  
import java.util.concurrent.TimeUnit;    
public class MainClass {  
    public static void main(String[] args) {  
       //新建普通客户窗口并启动  
       for(int i =1; i< 5; i++){  
           ServiceWindow commonWindow =new ServiceWindow();  
           commonWindow.setWindowId(i);  
           //启动普通窗口  
           commonWindow.start();  
       }  
       //新建快速窗口并启动  
       ServiceWindow expressWindow =new ServiceWindow();  
       expressWindow.setType(CustomerType.EXPRESS);  
       expressWindow.start();  
       //新建VIP窗口并启动  
       ServiceWindow vipWindow =new ServiceWindow();  
       vipWindow.setType(CustomerType.VIP);  
       vipWindow.start();    
       //模拟普通客户的到来   
       Executors.newScheduledThreadPool(1).scheduleAtFixedRate(  
              new Runnable(){   
                  public void run() {  
                     Integer number =  
                             NumberMachine.getInstance().getCommonManager().generateNewNumber();  
                     System.out.println(number+"号普通客户等待服务...");  
                  }  
              },  
              0,
              Constants.COMMON_CUSTOMER_INTERVAL_TIME,
              TimeUnit.SECONDS);    
       //模拟快速客户的到来  
       Executors.newScheduledThreadPool(1).scheduleAtFixedRate(  
              new Runnable(){    
                  public void run() {  
                     Integer number =  
                             NumberMachine.getInstance().getExpressManager().generateNewNumber();  
                     System.out.println(number+"号快速客户等待服务...");  
                  }  
              },  
              0,
              Constants.COMMON_CUSTOMER_INTERVAL_TIME*2,
              TimeUnit.SECONDS);  
       //模拟VIP客户的到来  
       Executors.newScheduledThreadPool(1).scheduleAtFixedRate(  
              new Runnable(){   
                  public void run() {  
                     Integer number =  
                            NumberMachine.getInstance().getVipManager().generateNewNumber();  
                     System.out.println(number+"号VIP客户等待服务...");  
                  }  
              },  
              0,
              Constants.COMMON_CUSTOMER_INTERVAL_TIME*6,
              TimeUnit.SECONDS);  
    }  
}

5.辅助类

(1)常量类

public class Constants {   
    public static final int MAX_SERVICE_INTERVAL_TIME =10000; //最大服务间隔时间  
    public static final int MIN_SERVICE_INTERVAL_TIME =1000;  //最小服务间隔时间 
    public static final int COMMON_CUSTOMER_INTERVAL_TIME =1; //普通客户间隔时间  
}

(2)枚举类

public enum CustomerType {    
    COMMON,EXPRESS,VIP;        
} 










  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值