黑马程序员--银行业务调度

来源:互联网 发布:个性化排序算法 编辑:程序博客网 时间:2024/05/11 08:40

---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IOS开发</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------

 

简单分析

1.如果要模拟银行调度只需两个实体 一个是号码  一个是窗口

2.根据业务需求号码有3中普通快速与vip 窗口有6个 其中4个普通1个快速一个vip

3.那么怎么把号码和窗口关联起来呢 你想想 号码作用生成一个个号码    窗口的作用就是把这一个个号码处理掉 这是不是就是数组 把号码存进去再取出来

4.那么我们就要一个主类  

---------    调用号码生成 但有3个不同的号码怎么生成  

---------    生成窗口 但有3种不同的窗口怎么区分

--------生成窗口调用方法 也就是从数组中取出号码 

-------还有就是号码的生成是3种类型同时生成的    这样就要开线程让3种号码同时生成

------主类主要目的是 模拟用户来取钱 窗口作出处理 号码代表用户


进一步分析

1.那么号码又怎么生成呢 

--------其实就是把自增的数放到数组中 或取出来

--------那么3种号码又怎么生成   其实就是生成3个数组 

--------那么这3种号码有怎么区分呢 就是怎么知道 一个号码到底是vip还是快速还是普通的号码呢      

老师是这么处理的   

1.号码管理者       他把生成号码放到一个类中 那么这个类的一个对象就是一个数组  这样还是区分不了 所以有出现了个号码生成机器 

2.号码生成机器(这个类是单例的也就是不能创建实例 只能用这个类给的实例)    这个类中放3个号码管理者(就是放3个数组) 并起不同的名字 commonManager,expressManager,vipManager

这样就做到了  commonManager 代表普通号码的存取  expressManager快速号码的存取 vipManager vip号码的存取


2.接下来就是窗口的处理

1.窗口的处理 也有3种不同的窗口 那么用不用像号码生成器一样定义3个窗口以做3种不同窗口的区分呢

其实不用的   我们可以在窗口类中定义一个变量 用来区分不同的窗口 在用到窗口的时候   窗口 实例传进不同的参数就可以了 

那么问题来了为什么号码管理者与号码生成器不用这种方法呢    

-------我的理解其实都是一样的 这种方法是在用的时候生成3个实例 而号码生成器是已经生成好的3个实例让你用 都一样的

2.那么类别老师又是怎么处理的 老师用的是枚举  也就是事先生成好3个实例 COMMON, EXPRESS, VIP 也就是普通快速与vip

下面是源代码

号码管理者 

public class NumberManager {    //定义自增变量与数组    private int lastNumber = 1;    private List<Integer> queueNumber = new ArrayList<Integer>();    //数组的存取  因为多线程访问所以 要存取要同步    public synchronized Integer generateNewManager(){        queueNumber.add(lastNumber);        return lastNumber++;         }        public synchronized Integer fetchServiceNumber(){        Integer number = null;        if(queueNumber.size()>0){            return  queueNumber.remove(0);        }        return number;           }        }



号码生成器

public class NumberMachine {    // 3个代码管理者 3个数组    private NumberManager commonManager = new NumberManager();    private NumberManager expressManager = new NumberManager();    private NumberManager vipManager = new NumberManager();    // 控制不能生产实例    private NumberMachine() {    };    private static NumberMachine instance = new NumberMachine();    public static NumberMachine getInstance() {        return instance;    }    // 只有属性的get方法就行    public NumberManager getCommonManager() {        return commonManager;    }    public NumberManager getExpressManager() {        return expressManager;    }    public NumberManager getVipManager() {        return vipManager;    }}
窗口

public class ServiceWindow {    // 定义枚举变量用于区分 不同窗口    private CustomerType type = CustomerType.COMMON;    private int windowId = 1;    public CustomerType getType() {        return type;    }    public void setType(CustomerType type) {        this.type = type;    }    public int getWindowId() {        return windowId;    }    public void setWindowId(int windowId) {        this.windowId = windowId;    }    // start()方法用于根据不同的枚举属性也就是不同的窗口 调用不同的方法    // 比如普通用户调用处理普通用户的方法   commonService();     //而普通方法做的就是 从普通的号码管理者中取出号码并睡眠一会  代表处理用户过程      public void start() {        Executors.newSingleThreadScheduledExecutor().execute(new Runnable() {            @Override            public void run() {                while (true) {                    switch (type) {                        case COMMON:                            commonService();                            break;                        case EXPRESS:                            expressService();                            break;                        case VIP:                            vipService();                            break;                    }                }            }            private void commonService() {                String windowName = "第" + windowId + "号" + type + "窗口";                System.out.println(windowName + "正在获取任务");                Integer number = NumberMachine.getInstance().getCommonManager().fetchServiceNumber();                if (number != null) {                    System.out.println(windowName + "为第" + number + "个" + type + "客户服务");                    long beginTime = System.currentTimeMillis();                    int maxRand = Constants.MAX_SERVICE_TIME - Constants.MIN_SERVICE_TIME;                    long serverTime = new Random().nextInt(maxRand) + 1 + Constants.MIN_SERVICE_TIME;                    try {                        Thread.sleep(serverTime);                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                    long endTime = System.currentTimeMillis();                    long costTime = endTime - beginTime;                    System.out.println(windowName + "为第" + number + "个" + type + "为客户完成任务耗时" + costTime                        / 1000 + "秒");                } else {                    System.out.println(windowName + "没有取到服务任务,先休息一秒");                    try {                        Thread.sleep(1000);                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }            }            private void expressService() {                String windowName = "第" + windowId + "号" + type + "窗口";                System.out.println(windowName + "正在获取任务");                Integer number = NumberMachine.getInstance().getExpressManager().fetchServiceNumber();                if (number != null) {                    long beginTime = System.currentTimeMillis();                    // int maxRand = Constants.MAX_SERVICE_TIME -                    // Constants.MIN_SERVICE_TIME;                    long serverTime = Constants.MIN_SERVICE_TIME;                    try {                        Thread.sleep(serverTime);                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                    long endTime = System.currentTimeMillis();                    long costTime = endTime - beginTime;                    System.out.println(windowName + "为第" + number + "个" + type + "为客户完成任务耗时" + costTime                        / 1000 + "秒");                } else {                    System.out.println(windowName + "没有取到服务任务");                    commonService();                    try {                        Thread.sleep(1000);                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }            }            private void vipService() {                String windowName = "第" + windowId + "号" + type + "窗口";                System.out.println(windowName + "正在获取任务");                Integer number = NumberMachine.getInstance().getVipManager().fetchServiceNumber();                if (number != null) {                    long beginTime = System.currentTimeMillis();                    int maxRand = Constants.MAX_SERVICE_TIME - Constants.MIN_SERVICE_TIME;                    long serverTime = new Random().nextInt(maxRand) + 1 + Constants.MIN_SERVICE_TIME;                    try {                        Thread.sleep(serverTime);                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                    long endTime = System.currentTimeMillis();                    long costTime = endTime - beginTime;                    System.out.println(windowName + "为第" + number + "个" + type + "为客户完成任务耗时" + costTime                        / 1000 + "秒");                } else {                    System.out.println(windowName + "没有取到服务任务");                    commonService();                    try {                        Thread.sleep(1000);                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }            }            // 匿名内部类结束        });    }}


还有就是主类 就是调用号码生成 与 窗户生成并处理号码   的类

public class MainClass {    public static void main(String[] args) {        // 普通用户窗口生成并执行start也就是处理普通用户  也就是从数组中取数据        for (int i = 1; i < 5; i++) {            ServiceWindow commonWindow = new ServiceWindow();            commonWindow.setWindowId(i);            commonWindow.start();        }        // 快速客户窗口生成并执行start也就是处理快速用户        ServiceWindow expressWindow = new ServiceWindow();        expressWindow.setType(CustomerType.EXPRESS);        expressWindow.start();        // vip客户窗口生成并执行start也就是处理vip用户        ServiceWindow vipWindow = new ServiceWindow();        vipWindow.setType(CustomerType.VIP);        vipWindow.start();        //接下来是开3个线程 生成3种不同的号码 模拟3种不同的客户 也就是生成号码放到数组中                Executors.newScheduledThreadPool(1).scheduleAtFixedRate(            new Runnable() {                public void run() {                                        Integer number = NumberMachine.getInstance().getCommonManager().generateNewManager();                    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().generateNewManager();                    System.out.println(number+"号快速客户等待服务");                }            },             0,             Constants.COMMON_CUSTOMER_INTERVAL_TIME  * 6,             TimeUnit.SECONDS);                Executors.newScheduledThreadPool(1).scheduleAtFixedRate(            new Runnable() {                public void run() {                                        Integer number = NumberMachine.getInstance().getVipManager().generateNewManager();                    System.out.println(number+"号vip客户等待服务");                }            },             0,             Constants.COMMON_CUSTOMER_INTERVAL_TIME  * 2,             TimeUnit.SECONDS);                                            }}

还有就是枚举类

public enum CustomerType {    COMMON, EXPRESS, VIP;        public String toString(){                switch(this){            case COMMON:                return "普通";            case EXPRESS:                return "快速";            case VIP:                return name();                   }        return null;     }}


附录 业务要求

银行业务调度系统

 

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

 

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

 

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

 

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

 

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

 

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

 

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

 

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

 

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

 

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

 



---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IOS开发</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------