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

来源:互联网 发布:网站数据库下载 编辑:程序博客网 时间:2024/06/06 00:23

------- 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);

       returnnextNumber++;

    }

    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 NumberManagerconNumber=new NumberManager();

    private NumberManagerExpNumber=new NumberManager();

    private NumberManagerVipNumber=new NumberManager();

    public NumberManager getConNumber() {

        returnconNumber;

    }

    public NumberManager getExpNumber() {

       returnExpNumber;

    }

    public NumberManager getVipNumber() {

       returnVipNumber;

    }

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

    public static NumberMachine getInstance(){

       returninstance;

    }

    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
原创粉丝点击