您的位置:首页 > 职场人生

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

2014-06-04 15:16 459 查看
银行调度业务系统

模拟实现银行业务调度系统逻辑,具体需求如下:

银行内有6个业务窗口,1 - 4号窗口为普通窗口,5号窗口为快速窗口,6号窗口为VIP窗口。

有三种对应类型的客户:VIP客户,普通客户,快速客户(办理如交水电费、电话费之类业务的客户)。

异步随机生成各种类型的客户,生成各类型用户的概率比例为:

VIP客户 :普通客户 :快速客户 = 1 :6 :3。

客户办理业务所需时间有最大值和最小值,在该范围内随机设定每个VIP客户以及普通客户办理业务所需的时间,快速客户办理业务所需时间为最小值(提示:办理业务的过程可通过线程Sleep的方式模拟)。

各类型客户在其对应窗口按顺序依次办理业务。

当VIP(6号)窗口和快速业务(5号)窗口没有客户等待办理业务的时候,这两个窗口可以处理普通客户的业务,而一旦有对应的客户等待办理业务的时候,则优先处理对应客户的业务。

随机生成客户时间间隔以及业务办理时间最大值和最小值自定,可以设置。

不要求实现GUI,只考虑系统逻辑实现,可通过Log方式展现程序运行结果。

分析:

    各种客户无论办理什么业务都需要取号,那么客户可以用取号机产生的号码来表示,通过一个号码管理器对象不断产生号码就等同于随机生成客户;由于有3类客户,且每类客户的号码编排是完全独立的,故需3个号码管理器对象各管理一类用户的排队号码,这3个号码管理器对象由一个号码机进行管理;而这个号码机在整个系统中始终只能有一个,故可设计为单例。

    各个窗口在办理所属业务之前都需要叫号,它需要问相应的号码管理器对象,即服务窗口通过号码管理器对象获取当前要被服务的号码。

分析类图:(Rational Rose统一建模语言)



  

代码设计:

1.自定义号码管理器类

public class NumberManager {

    /*号码管理器的基本属性*/

//用来记录生成的最新号码

    private int lastNumber=1;

//用来存储生成的号码供服务窗口获取

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

    /*提供生成号码的方法:将生成的号码存入排队队列中*/

    //由于该方法与获取号码的方法都在操作同一个数据,且工程设计多线程,需加同步

    public synchronized Integer createNumber(){

        numberQueue.add(lastNumber);

        return lastNumber++;

    }

    /*提供获取号码的方法:将号码提供给窗口,并将此号码从排队队列中删除*/

    public synchronized Integer getNumber(){

        //由于当集合中没有元素时,返回null,故返回类型为Integer比较方便

        if(numberQueue.size()!=0)

            return numberQueue.remove(0);

        return null;

    }

}

2.自定义号码机类

public class NumberMachine {

    /*号码机的基本属性*/

    //普通业务号码管理器、快速业务业务号码管理器、VIP业务号码管理器

    private NumberManager commonManager=new NumberManager();

    private NumberManager expressManager=new NumberManager();

    private NumberManager vipManager=new NumberManager();

    /*提供获取3类号码管理器的方法*/

    public NumberManager getCommonManager() {

        return commonManager;

    }

    public NumberManager getExpressManager() {

        return expressManager;

    }

    public NumberManager getVipManager() {

        return vipManager;

    }

    /*单例设计模式(饿汉式):保证本类对象的唯一性*/

    //构造方法私有化

    private NumberMachine(){}

    private static NumberMachine instance=new NumberMachine();

    //提供获取该类对象的静态方法

    public static NumberMachine getInstance(){

        return instance;

    }

}

3.自定义客户类型枚举类

public enum CustomerType {

    COMMON,EXPRESS,VIP;

    public String toString(){

        switch(this){

        case COMMON:return "普通";

        case EXPRESS:return "快速";

        case VIP:return "VIP";

        }

        return null;

    }

}

4.自定义常量类

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;

}

5.自定义服务窗口类

public class ServiceWindow {

    /*服务窗口的基本属性*/

//窗口服务类型,默认为普通业务

    private CustomerType type=CustomerType.COMMON;

    //窗口编号,默认为1号窗口

private int winID=1;

    /*设置服务窗口的基本属性*/

    public void setType(CustomerType type) {

        this.type = type;

    }

    public void setWinID(int winID) {

        this.winID = winID;

    }

    /*服务窗口开始提供服务的方法,即开启一条线程*/

    public void startService(){

        Executors.newSingleThreadExecutor().execute(new Runnable(){

            @Override

            public void run() {

                while(true){

                    switch(type){

                        case COMMON:

                            commonService();

                            break;

                        case EXPRESS:

                            expressService();

                            break;

                        case VIP:

                            vipService();

                            break;

                    }

                }

            }

        });

    }

    /*普通业务*/

    public void commonService(){

        //这里的type变量调用了枚举类的toString方法

String winName=winID+"号"+type+"窗口";

        Integer num=

NumberMachine.getInstance().getCommonManager().getNumber();

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

        //当获取到普通业务队列中的号码时,进行业务处理

        //当普通业务队列中无号码时,休息1秒钟后进行获取号码

        if(num!=null){

            System.out.println(winName+"正在为第"+num+"个普通客户服务!");

            long beginTime=System.currentTimeMillis();

            int maxRandom=

Constants.MAX_SERVICE_TIME-Constants.MIN_SERVICE_TIME;

            long serverTime=new Random().nextInt(maxRandom)

+1+Constants.MIN_SERVICE_TIME;

            try {

                //表示服务窗口正在处理任务

                Thread.sleep(serverTime);

            } catch (InterruptedException e) {

                e.printStackTrace();

            }

            long costTime=System.currentTimeMillis()-beginTime;

            System.out.println(winName+"为第"+num+

"个普通客户完成服务!耗时:"+(costTime/1000)+"秒");

        }else{

            System.out.println(winName+"没有获取到任务!休息1秒中。");

            try {

                Thread.sleep(1000);

            } catch (InterruptedException e) {

                e.printStackTrace();

            }

        }

    }

    /*快速业务*/

    public void expressService(){

        String winName=winID+"号"+type+"窗口";

        Integer num=

NumberMachine.getInstance().getExpressManager().getNumber();

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

        //当获取到快速业务队列中的号码时,进行业务处理

        //当快速业务队列中无号码时,处理普通业务

        if(num!=null){

            System.out.println(winName+"正在为第"+num+"个"

+type+"客户服务!");

            long beginTime=System.currentTimeMillis();

            long serverTime=Constants.MIN_SERVICE_TIME;

            try {

                Thread.sleep(serverTime);

            } catch (InterruptedException e) {

                e.printStackTrace();

            }

            long costTime=System.currentTimeMillis()-beginTime;

            System.out.println(winName+"为第"+num+"个"+type

+"客户完成服务!耗时:"+(costTime/1000)+"秒");

        }else{

            System.out.println(winName+"没有获取到任务!可办理普通业务。");

            commonService();

        }

    }

    /*VIP业务*/

    public void vipService(){

        String winName=winID+"号"+type+"窗口";

        Integer num=

NumberMachine.getInstance().getVipManager().getNumber();

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

        //当获取到VIP业务队列中的号码时,进行业务处理

        //当VIP业务队列中无号码时,处理普通业务

        if(num!=null){

            System.out.println(winName+"正在为第"+num+"个"

+type+"客户服务!");

            long beginTime=System.currentTimeMillis();

            int maxRandom=

Constants.MAX_SERVICE_TIME-Constants.MIN_SERVICE_TIME;

            long serverTime=

new Random().nextInt(maxRandom)+1+Constants.MIN_SERVICE_TIME;

            try {

                Thread.sleep(serverTime);

            } catch (InterruptedException e) {

                e.printStackTrace();

            }

            long costTime=System.currentTimeMillis()-beginTime;

            System.out.println(winName+"为第"+num+"个"+type

+"客户完成服务!耗时:"+(costTime/1000)+"秒");

        }else{

            System.out.println(winName+"没有获取到任务!可办理普通业务。");

            commonService();

        }

    }

}

6.主类

public class MainClass {

    public static void main(String[] args) {

        //开启窗口并启动窗口服务

        for(int i=1;i<5;i++){

            ServiceWindow commonWin=new ServiceWindow();

            commonWin.setWinID(i);

            commonWin.startService();

        }

        ServiceWindow expressWin=new ServiceWindow();

        setWin(expressWin,5,CustomerType.EXPRESS);

        ServiceWindow vipWin=new ServiceWindow();

        setWin(vipWin,6,CustomerType.VIP);

        //生成普通客户

        Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable(){

            @Override

            public void run() {

                int num=NumberMachine.getInstance()

.getCommonManager().createNumber();

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

            }

        },0,Constants.COMMON_CUSTOMER_INTERVAL_TIME,TimeUnit.SECONDS);

        //生成快速客户

        Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable(){

            @Override

            public void run() {

                int num=NumberMachine.getInstance()

.getExpressManager().createNumber();

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

            }

        },0,Constants.COMMON_CUSTOMER_INTERVAL_TIME*2,TimeUnit.SECONDS);

        //生成VIP客户

        Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable(){

            @Override

            public void run() {

                int num=NumberMachine.getInstance()

.getVipManager().createNumber();

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

            }

        },0,Constants.COMMON_CUSTOMER_INTERVAL_TIME*6,TimeUnit.SECONDS);

    }

    //设置服务窗口属性

    public void setWin(ServiceWindow win, int id,CustomerType type){

        win.setWinID(id);

        win.setType(type);

        win.startService();

    }

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: