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

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

首先明确有三种对应类型的客户:VIP客户,普通客户,快速客户,异步随机生成各种类型的客户,各类型客户在其对应窗口按顺序依次办理业务。

其次,需要一个号码管理器对象,由于有三类客户,且每类客户号码的编排都是完全独立的,所以该系统中一共要产生三个号码管理器对象,各自管理一类客户的编排号码。这三个号码管理器对象统一的由一个号码机器进行管理,这个号码机器在整个系统中始终只能有一个,所以该机器对象要使用单例设计模式进行设计。

接着是各个类型的客户在其对应窗口按顺序依次办理业务,准确的说,就是窗口依次叫号。各个窗口叫号的的方式就是问相应的号码管理器,即重口每次找号码管理器获取当前要被服务的号码。

所以综上所述,需要以下相应的对象:

1、               号码管理机对象:NumberMachine——>包含有三种获取不同号码的方法:getConMannager().getVipMannager().getExpMannager().getInstance().

2、               管理三类号码器:NumberManager——>包含产生号码的方式:newGenerateNumber().窗口即将获取的服务号码er()

3、               服务窗口对象:ServiceWindow——>执行取号、叫号等任务

 

相关代码如下:

号码产生器:NumberManager类

package cn.bank.interviw;

import java.util.ArrayList;

import java.util.List;

public class NumberManager {//号码产生器

    private int nextNumber=1;

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

    public synchronized Integer newGenerateNewManager(){//产生新号码 ,客户获取号码

       //每次产生一个号码就将该号码储存起来

       queueNumber.add(nextNumber);

       return nextNumber++;

    }

    public synchronized Integer fetchServiceNumber(){//窗口获取队列服务号码

       Integer num=null;

       if(queueNumber.size()>0){

           num=queueNumber.remove(0);//获取服务的下一个服务号

       }

       return num;

    }

}

注意:

在方法上加synchronized的理由是:由于是两个不同的线程调用这两个方法,同时两个线程访问相同的数据,就会出现问题,需要让该两个线程产生互斥。。。

 

方法中的int改为Integer的理由:当拿号时,当集合为空时即返回null,集合储存的是对象,null转成int型会产生空指针异常

 

号码管理器:NumberMachine类

package cn.bank.interviw;

public class NumberMachine {//号码管理器

    //需要返回三个号码产生器

    private NumberManager conNumber=new NumberManager();

    private NumberManager ExpNumber=new NumberManager();

    private NumberManager VipNumber=new NumberManager();

    public NumberManager getConNumber() {

        return conNumber;

    }

    public NumberManager getExpNumber() {

       return ExpNumber;

    }

    public NumberManager getVipNumber() {

       return VipNumber;

    }

    private NumberMachine(){}//私有化构造方法,采用单例设计模式

    public static NumberMachine getInstance(){

       return instance;

    }

    private static NumberMachine instance = new NumberMachine();

}

 

在定义服务窗口时,需要使用枚举方式将三种客户类型例举出来

package cn.bank.interviw;

 

public enum CustomType {

    COMMON,EXPRESS,VIP;//三种客户类型对象

    public String toString(){

       switch(this){

       case COMMON:

           return "普通";

       case EXPRESS:

           return "快速";

       case VIP:

           return "VIP"(name());

       }

       return null;

    }

}

其次,常量类

package cn.bank.interviw;

public class Constants {

    //常量需要定义一个专门的类

    public static int MAX_SERVICE_TIME=10000;

    public static int MIN_SERVICE_TIME=1000;

    public static int COMMOM_CUSTOMER_INTERVAL_TIME=1;

}

 

窗口服务:ServiceWindow类

package cn.bank.interviw;

 

import java.util.Random;

import java.util.concurrent.Executors;

 

public class ServiceWindow {

 

    privateCustomType type=CustomType.COMMON;//首先默认该窗口类型是普通型

    privateint windowId=1;//为窗口编号

   

    publicvoid setType(CustomType type) {

       this.type= type;

    }

    publicvoid setIndowId(int windowId) {

       this.windowId= windowId;

    }

   

    //叫号

    publicvoid start(){//开始叫号,启动一个线程,不停得叫号

       Executors.newSingleThreadExecutor().execute(newRunnable(){

           @Override

           publicvoid run(){

              //窗口叫号

              while(true){

                  //窗口叫号:考虑是哪个类型的窗口叫号。

                  //只有三种类型的窗口进行叫号,所以采用枚举的方式列出三种类型

                  switch(type){

                  caseCOMMON:

                     comService();

                     break;

                  caseEXPRESS:

                     expService();

                     break;

                  caseVIP:

                     vipService();

                     break;

                  }

              }

           }

       });

    }

    privatevoid vipService() {

       //TODO Auto-generated method stub

       StringwindowName="第"+windowId+"号"+type+"窗口";

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

       Integernum=NumberMachine.getInstance().getConNumber().fetchServiceNumber();

       if(num!=null){

           System.out.println(windowName+"为第"+num+"个"+type+"客户成服务");

           longbeginTime=System.currentTimeMillis();

           intmaxServiceTime=Constants.MAX_SERVICE_TIME-Constants.MIN_SERVICE_TIME;

           longserviceTimne=new Random().nextInt(maxServiceTime)+1+Constants.MIN_SERVICE_TIME;

           try{

              Thread.sleep(serviceTimne);

           }catch (InterruptedException e) {

              //TODO Auto-generated catch block

              e.printStackTrace();

           }

           longcostTime=System.currentTimeMillis()-beginTime;

           System.out.println(windowName+"为第"+num+"个"+type+"客户完成服务,耗时"+costTime/1000+"秒");

       }else{

           System.out.println(windowName+"没有取到服务任务");

           comService();

       }

    }

 

    privatevoid expService() {

       //TODO Auto-generated method stub

       StringwindowName="第"+windowId+"号"+type+"窗口";

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

       Integernum=NumberMachine.getInstance().getExpNumber().fetchServiceNumber();

       if(num!=null){

           System.out.println(windowName+"为第"+num+"个"+type+"客户成服务");

           longbeginTime=System.currentTimeMillis();

           //intmaxServiceTime=Constants.MAX_SERVICE_TIME-Constants.MIN_SERVICE_TIME;

           //longserviceTimne=new Random().nextInt(maxServiceTime)+1+Constants.MIN_SERVICE_TIME;

           try{

              Thread.sleep(Constants.MIN_SERVICE_TIME);

           }catch (InterruptedException e) {

              //TODO Auto-generated catch block

              e.printStackTrace();

           }

           longcostTime=System.currentTimeMillis()-beginTime;

           System.out.println(windowName+"为第"+num+"个"+type+"客户完成服务,耗时"+costTime/1000+"秒");

       }else{

           System.out.println(windowName+"没有取到服务任务");

           comService();

       }

    }

    privatevoid comService() {

       StringwindowName="第"+windowId+"号"+type+"窗口";

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

       Integernum=NumberMachine.getInstance().getConNumber().fetchServiceNumber();

       if(num!=null){

           System.out.println(windowName+"为第"+num+"个"+type+"客户成服务");

           longbeginTime=System.currentTimeMillis();

           intmaxServiceTime=Constants.MAX_SERVICE_TIME-Constants.MIN_SERVICE_TIME;

           longserviceTimne=new Random().nextInt(maxServiceTime)+1+Constants.MIN_SERVICE_TIME;

           try{

              Thread.sleep(serviceTimne);

           }catch (InterruptedException e) {

              //TODO Auto-generated catch block

              e.printStackTrace();

           }

           longcostTime=System.currentTimeMillis()-beginTime;

           System.out.println(windowName+"为第"+num+"个"+type+"客户完成服务,耗时"+costTime/1000+"秒");

       }else{

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

       }

       try{

           Thread.sleep(1000);

       }catch (InterruptedException e) {

           //TODO Auto-generated catch block

           e.printStackTrace();

       }

    }

}

//if else没有switch效率高:switch的数据类型只能是int和Enum类型

 

主函数:MainRun类

package cn.bank.interviw;

import java.util.concurrent.Executors;

import java.util.concurrent.TimeUnit;

public class MainRun {

    publicstatic void main(String[] args) {

       for(inti=1;i<5;i++){//产生四个普通通服务窗口

           ServiceWindowcomServiceWindow=new ServiceWindow();

           comServiceWindow.setIndowId(i);

           comServiceWindow.start();      

       }

       //产生一个VIP窗口

       ServiceWindowvipServiceWindow=new ServiceWindow();

       vipServiceWindow.setType(CustomType.VIP);

       vipServiceWindow.start();

       //产生一个快速窗口

       ServiceWindowexpServiceWindow=new ServiceWindow();

       expServiceWindow.setType(CustomType.EXPRESS);

       expServiceWindow.start();

       //普通窗口服务

       Executors.newScheduledThreadPool(1).scheduleAtFixedRate(

              newRunnable(){

                  publicvoid run(){

Integer num=

NumberMachine.getInstance().getConNumber().newGenerateNewManager();

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

                  }

              },

              0,

              Constants.COMMOM_CUSTOMER_INTERVAL_TIME,

              TimeUnit.SECONDS);

       //快速窗口服务

       Executors.newScheduledThreadPool(1).scheduleAtFixedRate(

              newRunnable(){

                  publicvoid run(){

Integer num=

NumberMachine.getInstance().getExpNumber().newGenerateNewManager();

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

                  }

              },

              0,

              Constants.COMMOM_CUSTOMER_INTERVAL_TIME*2,

              TimeUnit.SECONDS);

       //VIP窗口服务

       Executors.newScheduledThreadPool(1).scheduleAtFixedRate(

              newRunnable(){

                  publicvoid run(){

Integer num=

NumberMachine.getInstance().getVipNumber().newGenerateNewManager();

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

                  }

              },

              0,

              Constants.COMMOM_CUSTOMER_INTERVAL_TIME*6,

              TimeUnit.SECONDS);

    }

 

}

 

总的来说,银行调度系统比交通灯模拟更加复杂。但是,两个实例是换汤不换药,主要分析清楚对象,需要哪些对象,如何定义这类对象的类。

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值