项目分析及设计
1.有三种对应类型的客户:VIP客户,普通客户,快速客户 ,异步随机生成各种类型的客户,各类型客户在其对应窗口按顺序依次办理务。
2.首先,知道每一个客户其实就是由银行的一个取号机器产生号码的方式来表示的。所以,要有一个号码管理器对象,让这个对象不断地产生号码,就等于随机生成了客户。由于有三类客户,每类客户的号码编排都是完全独立的,所以,本系统一共要产生三个号码管理器对象,各自管理一类用户的排队号码。这三个号码管理器对象统一由一个号码机器进行管理,这个号码机器在整个系统中始终只能有一个,所以,它要被设计成单例。各类型客户在其对应窗口按顺序依次办理业务,准确地说,应该是窗口依次叫号。各个窗口怎么知道该叫哪一个号了呢?它一定是问的相应的号码管理器,即服务窗口每次找号码管理器获取当前要被服务的号码。
代码实现如下:
NumberManager类实现:
package com.isoftstone.interview.bank; import java.util.List; import java.util.ArrayList; public class NumberManager { private int lastNumber = 1; private List<Integer> queueNumber = new ArrayList<Integer>(); public synchronized Integer generateNewNumber(){ queueNumber.add(lastNumber); return this.lastNumber ++; } public synchronized Integer fetchServiceNumber(){ if(queueNumber.size() > 0) return queueNumber.remove(0); return null; } }
NumberMachine类实现:
package com.isoftstone.interview.bank; public class NumberMachine { //产生不同客户 private NumberManager commonManager = new NumberManager(); private NumberManager expressManager = new NumberManager(); private NumberManager vipManager = new NumberManager(); 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; } }
ServiceWindow类实现:
package com.isoftstone.interview.bank; import java.util.Random; import java.util.concurrent.Executors; public class ServiceWindow { private CustomerType type = CustomerType.COMMAN; private int windowId = 1; public void setType(CustomerType type) { this.type = type; } public void setWindowId(int windowId) { this.windowId = windowId; } void star(){ Executors.newSingleThreadExecutor().execute(new Runnable(){ public void run(){ while(true){ switch(type){ case COMMAN: commonServica(); break; case EXPRESS: expressServica(); break; case VIP: vipServica(); break; } } } }); } private void commonServica() { String windowName = "第" + windowId + "号" + type + "窗口"; Integer number = NumberMachine.getInstance().getCommonManager().fetchServiceNumber(); System.out.println(windowName + "正在取普通号"); if(number != null){ System.out.println(windowName + "正在为第" + number + "个普通客户服务"); long beginTime = System.currentTimeMillis(); int randTime = Constants.MAX_TIME - Constants.MIN_TIME; long serveTime = new Random().nextInt(randTime) + 1 + Constants.MIN_TIME; try { Thread.sleep(serveTime); } catch (InterruptedException e) { e.printStackTrace(); } long endTime = System.currentTimeMillis(); System.out.println(windowName + "为第" + number + "个" + type + "客户完成服务,耗时" + (endTime - beginTime)/1000 + "秒"); } else { System.out.println(windowName + "没有取到号,休息一秒"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } private void expressServica() { String windowName = "第" + windowId + "号" + type + "窗口"; Integer number = NumberMachine.getInstance().getExpressManager().fetchServiceNumber(); System.out.println(windowName + "正在取expres号"); if(number != null){ System.out.println(windowName + "正在为第" + number + "个" + type + "客户服务"); long beginTime = System.currentTimeMillis(); long serveTime = Constants.MIN_TIME; try { Thread.sleep(serveTime); } catch (InterruptedException e) { e.printStackTrace(); } long endTime = System.currentTimeMillis(); System.out.println(windowName + "为第" + number + "个" + type + "客户完成服务,耗时" + (endTime - beginTime)/1000 + "秒"); } else { System.out.println(windowName + "没有取到号"); commonServica(); } } private void vipServica() { String windowName = "第" + windowId + "号" + type + "窗口"; Integer number = NumberMachine.getInstance().getVipManager().fetchServiceNumber(); System.out.println(windowName + "正在取vip号"); if(number != null){ System.out.println(windowName + "正在为第" + number + "个" + type + "客户服务"); long beginTime = System.currentTimeMillis(); int randTime = Constants.MAX_TIME - Constants.MIN_TIME; long serveTime = new Random().nextInt(randTime) + 1 + Constants.MIN_TIME; try { Thread.sleep(serveTime); } catch (InterruptedException e) { e.printStackTrace(); } long endTime = System.currentTimeMillis(); System.out.println(windowName + "为第" + number + "个" + type + "客户完成服务,耗时" + (endTime - beginTime)/1000 + "秒"); } else { System.out.println(windowName + "没有取到号"); commonServica(); } } }
CustomerType类实现:
package com.isoftstone.interview.bank; public enum CustomerType { COMMAN,EXPRESS,VIP; public String toString(){ switch(this){ case COMMAN : return "普通"; case EXPRESS : return "快速"; case VIP : return name(); } return null; } }
MainClass类实现:
package com.isoftstone.interview.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.star(); } //产生一个VIP窗口 ServiceWindow vipWindow = new ServiceWindow(); vipWindow.setType(CustomerType.VIP); vipWindow.star(); //产生一个快速窗口 ServiceWindow expressWindow = new ServiceWindow(); expressWindow.setType(CustomerType.EXPRESS); expressWindow.star(); //普通客户拿号 Executors.newScheduledThreadPool(1).scheduleWithFixedDelay( new Runnable(){ @Override public void run() { int number = NumberMachine.getInstance().getCommonManager().generateNewNumber(); System.out.println(number + "普通客服正在等待服务"); } }, 0, 1, TimeUnit.SECONDS); //vip客户拿号 Executors.newScheduledThreadPool(1).scheduleWithFixedDelay( new Runnable(){ @Override public void run() { int number = NumberMachine.getInstance().getVipManager().generateNewNumber(); System.out.println(number + "号vip客服正在等待服务"); } }, 0, 6, TimeUnit.SECONDS); //快速客户拿号 Executors.newScheduledThreadPool(1).scheduleWithFixedDelay( new Runnable(){ @Override public void run() { int number = NumberMachine.getInstance().getExpressManager().generateNewNumber(); System.out.println(number + "号快速客服正在等待服务"); } }, 0, 3, TimeUnit.SECONDS); } }
Constants类:
package com.isoftstone.interview.bank; public class Constants { public static int MAX_TIME = 10000; public static int MIN_TIME = 1000; }
注:参照了网上一些内容。