黑马程序员 java基础加强之银行业务调度系统
//定义一个生成号码的类 public class NumberManager { private int lastNumber = 1; //该容器用来接收客户号码 List<Integer> queue = new ArrayList<Integer>(); //生成号码的方法,将号码存入集合中保存,需要线程安全 public synchronized Integer generateNewManager(){ queue.add(lastNumber); return lastNumber++; } //窗口取号的方法,移除掉集合中第一位,需要线程安全 public synchronized Integer fetchServiceNumber(){ if(queue.size() > 0){ return (Integer)queue.remove(0); }else{ return null; } } } //定义一个号码管理机器,将不同客户的号码放到同一个机器中 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 static NumberMachine numberMachine = new NumberMachine(); public static NumberMachine getInstence(){ return numberMachine; } } 2、各类型客户在其对应窗口按顺序依次办理业务 ,根据面向对象设计分析,这里应该把窗口作为对象,不同的窗口提供不同的服务。 至于各个窗口该叫哪一个号,它应该去问相应的号码管理器,即服务窗口每次找号码管理器获取当前要被服务的号码。代码如下: public class ServiceWindow { //先获取机器的对象,从机器中获取号码 NumberMachine numberMachine = NumberMachine.getInstence(); //客户类型只有三种固定类型,所以定义在类中作为常量,默认普通 private CostomerType type = CostomerType.COMMON; //窗口的ID,默认为1,提供set方法改变这个值 private int windowId = 1; public void setType(CostomerType type) { this.type = type; } public void setWindowId(int windowId) { this.windowId = windowId; } //开始服务 public void start(){ //放到线程池中执行 Executors.newSingleThreadExecutor().execute(new Runnable(){ 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.getCommonManager().fetchServiceNumber(); if(number != null){ //办理业务 long beginTime = System.currentTimeMillis(); //随机生成办理客户业务需要花费的时间,办理业务花费时间的最大值和最小值作为常亮定义在Contants类中 int maxRandomTime = Constants.MAX_SERVICE_TIME - Constants.MIN_SERVICE_TIME; int serveTime = new Random().nextInt(maxRandomTime)+1+Constants.MIN_SERVICE_TIME; try { Thread.sleep(serveTime); } catch (InterruptedException e) { e.printStackTrace(); } long costTime = System.currentTimeMillis() - beginTime; System.out.println(windowName + "正在为第"+ number+ "位普通客户服务,耗时" + costTime/1000 + "秒"); //如果没有客户,休息1秒再叫号。 }else{ System.out.println(windowName + "没有取到任务,休息一下"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } //快速窗口服务 private void expressService() { String windowName = "第"+ windowId+"号快速窗口"; System.out.println(windowName + "正在获取任务"); Integer number = numberMachine.getExpressManager().fetchServiceNumber(); if(number != null){ long beginTime = System.currentTimeMillis(); try { //项目需要快速窗口办理业务所需时间为最小值。 Thread.sleep(Constants.MIN_SERVICE_TIME); } catch (InterruptedException e) { e.printStackTrace(); } long serveTime = System.currentTimeMillis() - beginTime; System.out.println(windowName + "正在为第"+ number+ "位快速客户服务,耗时" + serveTime/1000 + "秒"); }else{ System.out.println(windowName + "没有取到任务,开始办理普通客户"); //没有快速客户时办理普通窗口的业务 commonService(); } } //vip窗口服务 private void vipService() { String windowName = "第"+ windowId+"号VIP窗口"; System.out.println(windowName + "正在获取任务"); Integer number = numberMachine.getVipManager().fetchServiceNumber(); if(number != null){ long beginTime = System.currentTimeMillis(); int maxRandomTime = Constants.MAX_SERVICE_TIME - Constants.MIN_SERVICE_TIME; int serveTime = new Random().nextInt(maxRandomTime)+1+Constants.MIN_SERVICE_TIME; try { Thread.sleep(serveTime); } catch (InterruptedException e) { e.printStackTrace(); } long costTime = System.currentTimeMillis() - beginTime; System.out.println(windowName + "正在为第"+ number+ "位VIP客户服务,耗时" + costTime/1000 + "秒"); }else{ System.out.println(windowName + "没有取到任务,开始办理普通客户"); //没有Vip客户时办理普通客户业务 commonService(); } } }
服务窗口类
public class ServiceWindow { //先获取机器的对象,从机器中获取号码 NumberMachine numberMachine = NumberMachine.getInstence(); //客户类型只有三种固定类型,所以定义在类中作为常量,默认普通 private CostomerType type = CostomerType.COMMON; //窗口的ID,默认为1,提供set方法改变这个值 private int windowId = 1; public void setType(CostomerType type) { this.type = type; } public void setWindowId(int windowId) { this.windowId = windowId; } //开始服务 public void start(){ //放到线程池中执行 Executors.newSingleThreadExecutor().execute(new Runnable(){ 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.getCommonManager().fetchServiceNumber(); if(number != null){ //办理业务 long beginTime = System.currentTimeMillis(); //随机生成办理客户业务需要花费的时间,办理业务花费时间的最大值和最小值作为常亮定义在Contants类中 int maxRandomTime = Constants.MAX_SERVICE_TIME - Constants.MIN_SERVICE_TIME; int serveTime = new Random().nextInt(maxRandomTime)+1+Constants.MIN_SERVICE_TIME; try { Thread.sleep(serveTime); } catch (InterruptedException e) { e.printStackTrace(); } long costTime = System.currentTimeMillis() - beginTime; System.out.println(windowName + "正在为第"+ number+ "位普通客户服务,耗时" + costTime/1000 + "秒"); //如果没有客户,休息1秒再叫号。 }else{ System.out.println(windowName + "没有取到任务,休息一下"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } //快速窗口服务 private void expressService() { String windowName = "第"+ windowId+"号快速窗口"; System.out.println(windowName + "正在获取任务"); Integer number = numberMachine.getExpressManager().fetchServiceNumber(); if(number != null){ long beginTime = System.currentTimeMillis(); try { //项目需要快速窗口办理业务所需时间为最小值。 Thread.sleep(Constants.MIN_SERVICE_TIME); } catch (InterruptedException e) { e.printStackTrace(); } long serveTime = System.currentTimeMillis() - beginTime; System.out.println(windowName + "正在为第"+ number+ "位快速客户服务,耗时" + serveTime/1000 + "秒"); }else{ System.out.println(windowName + "没有取到任务,开始办理普通客户"); //没有快速客户时办理普通窗口的业务 commonService(); } } //vip窗口服务 private void vipService() { String windowName = "第"+ windowId+"号VIP窗口"; System.out.println(windowName + "正在获取任务"); Integer number = numberMachine.getVipManager().fetchServiceNumber(); if(number != null){ long beginTime = System.currentTimeMillis(); int maxRandomTime = Constants.MAX_SERVICE_TIME - Constants.MIN_SERVICE_TIME; int serveTime = new Random().nextInt(maxRandomTime)+1+Constants.MIN_SERVICE_TIME; try { Thread.sleep(serveTime); } catch (InterruptedException e) { e.printStackTrace(); } long costTime = System.currentTimeMillis() - beginTime; System.out.println(windowName + "正在为第"+ number+ "位VIP客户服务,耗时" + costTime/1000 + "秒"); }else{ System.out.println(windowName + "没有取到任务,开始办理普通客户"); //没有Vip客户时办理普通客户业务 commonService(); } } }
辅助类
//客户类型 public enum CostomerType { COMMON,EXPRESS,VIP; //为了在控制台获取类型的名字,重写toString方法 public String toString(){ switch(this){ case COMMON: return "普通"; case EXPRESS: return "快速"; case VIP: return name(); } return null; } } //项目中用到的所有常亮 public class Constants { //客户办理业务花费的最大值10秒和最小值1秒 public static int MAX_SERVICE_TIME = 10000; public static int MIN_SERVICE_TIME = 1000; //生成一个普通客户的时间间隔 public static int COMMON_CUSTOMER_INTERVAL_TIME = 1; }
测试类
//主类,生成服务窗口,并模拟产生客户 public class MainClass { public static void main(String[] args) { //生成四个普通窗口并开始服务 for (int i = 1; i < 5; i++) { ServiceWindow commonWindow = new ServiceWindow(); commonWindow.setWindowId(i); commonWindow.start(); } //生成一个快速窗口 ServiceWindow expressWindow = new ServiceWindow(); expressWindow.setType(CostomerType.EXPRESS); expressWindow.start(); //生成一个VIP窗口 ServiceWindow vipWindow = new ServiceWindow(); vipWindow.setType(CostomerType.VIP); vipWindow.start(); //模拟生成普通客户 Executors.newScheduledThreadPool(1).scheduleAtFixedRate( new Runnable(){ public void run() { Integer number = NumberMachine.getInstence().getCommonManager().generateNewManager(); System.out.println("第"+number+"号普通客户等待服务"); } }, , Constants.COMMON_CUSTOMER_INTERVAL_TIME, TimeUnit.SECONDS); //模拟生成快速客户 Executors.newScheduledThreadPool(1).scheduleAtFixedRate( new Runnable(){ public void run() { Integer number = NumberMachine.getInstence().getExpressManager().generateNewManager(); System.out.println("第"+number+"号快速客户等待服务"); } }, , Constants.COMMON_CUSTOMER_INTERVAL_TIME * 2, TimeUnit.SECONDS); //模拟生成VIP客户 Executors.newScheduledThreadPool(1).scheduleAtFixedRate( new Runnable(){ public void run() { Integer number = NumberMachine.getInstence().getVipManager().generateNewManager(); System.out.println("第"+number+"号VIP客户等待服务"); } }, , Constants.COMMON_CUSTOMER_INTERVAL_TIME * 6, TimeUnit.SECONDS); } }