银行业务调度系统-心得2-项目源码即注释
2013-01-28 19:53
549 查看
1. 主要类,连带着测试输出 MainClass.java package com.family.audition; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; public class MainClass { /** * @param args */ public static void main(String[] args) { // 产生4个普通窗口;必须从1开始,因为实际银行中没有0号窗口 for (int i = 1; i < 5; i++) { ServiceWindow commonWindow = new ServiceWindow(); commonWindow.setNumber(i); commonWindow.start(); } // 产生1个快速窗口 ServiceWindow expressWindow = new ServiceWindow(); expressWindow.setType(CustomerType.EXPRESS); expressWindow.start(); // 产生1个vip窗口 ServiceWindow vipWindow = new ServiceWindow(); vipWindow.setType(CustomerType.VIP); vipWindow.start(); //下面用到的技术不是普通的线程池,而是调度线程池,相当于连续的定时炸弹 // 普通客户拿号 Executors .newScheduledThreadPool(1) .scheduleWithFixedDelay( //改方法的第一个参数,一个命令 new Runnable() { @Override public void run() { Integer serviceNumber = NumberMachine.getInstance() .getCommonManager().generateNumber(); /** * 采用logger方式,无法看到直观的运行效果,因为logger.log方法内部并不是直接把内容打印出出来, * 而是交给内部的一个线程去处理,所以,打印出来的结果在时间顺序上看起来很混乱。 */ // logger.info("第" + serviceNumber + "号普通客户正在等待服务!"); System.out .println("第" + serviceNumber + "号普通客户正在等待服务!"); } }, 0, //多长时间来一个人 Constants.COMMON_CUSTOMER_INTERVAL_TIME, //隔多长时间再来一个 TimeUnit.SECONDS //以秒为单位 ); // 快速客户拿号 Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() { public void run() { Integer serviceNumber = NumberMachine.getInstance() .getExpressManager().generateNumber(); System.out.println("第" + serviceNumber + "号快速客户正在等待服务!"); } }, 0, Constants.COMMON_CUSTOMER_INTERVAL_TIME * 3, TimeUnit.SECONDS); //生成各类型用户的概率比例:需求上普通:快速:vip是1:6:3 // VIP客户拿号 Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() { public void run() { Integer serviceNumber = NumberMachine.getInstance() .getVipManager().generateNumber(); System.out.println("第" + serviceNumber + "号VIP客户正在等待服务!"); } }, 0, Constants.COMMON_CUSTOMER_INTERVAL_TIME * 6, TimeUnit.SECONDS); } } 2. 号码管理器,其中有对应的号码生成器和窗口叫号器方法 NumberManager.java package com.family.audition; import java.util.ArrayList; import java.util.List; public class NumberManager { private int lastNumber = 0; private List orderNumber = new ArrayList(); //号码生成器,模拟客户序列号 public synchronized Integer generateNumber(){ orderNumber.add(++lastNumber); return lastNumber; } //银行窗口叫号器 public synchronized Integer fetchNumber(){ if(orderNumber.size()>0){ return (Integer) orderNumber.remove(0); }else{ return null; } } } 3. 取号机器 NumberMachine.java package com.family.audition; public class NumberMachine { //单例模式,对外开放一个构造方法实例 private NumberMachine(){} private static NumberMachine instance = new NumberMachine(); public static NumberMachine getInstance(){ return instance; } //生成不同身份的客户对应的对外get方法 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; } } 4.服务窗口 ServiceWindow.java package com.family.audition; import java.util.Random; import java.util.concurrent.Executors; /** * 可能有的人认为把vip和快速窗口做成普通窗口的子类代码显得更优化、更简单; * 这里没有把VIP窗口和快速窗口做成子类,是因为实际业务中的普通窗口可以随时被设置为VIP窗口和快速窗口。 * */ public class ServiceWindow { private CustomerType type = CustomerType.COMMON; private int number = 1; public CustomerType getType() { return type; } public void setType(CustomerType type) { this.type = type; } public void setNumber(int number) { this.number = number; } public void start() { //new 一个线程池;jdk5新特性中的知识 Executors.newSingleThreadExecutor().execute(new Runnable() { @Override public void run() { // 下面这种写法代码简单但是的运行效率低,最好是把while放在case下面 while (true) { switch (type) { case COMMON: commonService(); break; case EXPRESS: expressService(); break; case VIP: vipService(); break; } } } }); } //为普通用户服务的方法 protected void commonService() { String windowName = number + "号" + type + "窗口"; System.out.println(windowName + "开始获取普通任务!"); Integer serviceNumber = NumberMachine.getInstance().getCommonManager() .fetchNumber(); if (serviceNumber != null) { //这里输出的时候不能使用type来代替相应的汉字输出了,否则在快速和vip窗口的方法调用普通方法的时候会不出现办理普通用户的信息 System.out.println(windowName + "开始为第" + serviceNumber + "号普通客户服务"); int maxRandom = Constants.MAX_SERVICE_TIME - Constants.MIN_SERVICE_TIME; // 为客户办理业务时间为1到10秒内随机时间 int serviceTime = new Random().nextInt(maxRandom) + 1 + Constants.MIN_SERVICE_TIME; try { Thread.sleep(serviceTime); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(windowName + "完成为第" + serviceNumber + "号普通客户服务,总共耗时" + serviceTime / 1000 + "秒"); } else { //没有取到普通任务,正在空闲一秒 System.out.println(windowName + "没有取到普通任务,正在空闲一秒"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } //为快速用户服务的方法 protected void expressService() { Integer serviceNumber = NumberMachine.getInstance().getExpressManager().fetchNumber(); String windowName = "第" + number + "号" + type + "窗口"; System.out.println(windowName + "开始获取快速任务!"); if(serviceNumber !=null){ System.out.println(windowName + "开始为第" + serviceNumber + "号快速客户服务"); int serviceTime = Constants.MIN_SERVICE_TIME; try { Thread.sleep(serviceTime); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(windowName + "完成为第" + serviceNumber + "号快速客户服务,总共耗时" + serviceTime/1000 + "秒"); }else{ System.out.println(windowName + "没有取到快速任务!"); //不休息,如果没有快速客户,开始办理普通客户业务 commonService(); } } //为VIP用户服务的方法 private void vipService(){ Integer serviceNumber = NumberMachine.getInstance().getVipManager().fetchNumber(); String windowName = "第" + number + "号" + type + "窗口"; System.out.println(windowName + "开始获取VIP任务!"); if(serviceNumber !=null){ System.out.println(windowName + "开始为第" + serviceNumber + "号VIP客户服务"); int maxRandom = Constants.MAX_SERVICE_TIME - Constants.MIN_SERVICE_TIME; int serviceTime = new Random().nextInt(maxRandom)+1 + Constants.MIN_SERVICE_TIME; try { Thread.sleep(serviceTime); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(windowName + "完成为第" + serviceNumber + "号VIP客户服务,总共耗时" + serviceTime/1000 + "秒"); }else{ System.out.println(windowName + "没有取到VIP任务!"); //不休息,如果没有vip客户,开始办理普通客户业务 commonService(); } } } 5.服务窗口辅助类 枚举类 客户类型选择 CusomerType.java package com.family.audition; public enum CustomerType { COMMON, EXPRESS, VIP; // 重写父类的toString()方法,使返回中文类型提示 public String toString(){ String name = null; switch(this){ case COMMON: name = "普通"; break; case EXPRESS: name = "快速"; break; case VIP: //枚举类内部有个name()方法就是返回一个枚举类型的值本身 name = name(); break; } return name; } } 6.服务窗口辅助类 休眠时间控制Constants类 package com.family.audition; public class Constants { public static int MAX_SERVICE_TIME = 10000; //最大服务时间10秒 public static int MIN_SERVICE_TIME = 1000; //最小服务时间1秒 /*每个普通窗口服务一个客户的平均时间为5秒,一共有4个这样的窗口,也就是说银行的所有普通窗口合起来 * 平均1.25秒内可以服务完一个普通客户,再加上快速窗口和VIP窗口也可以服务普通客户,所以, * 1秒钟产生一个普通客户比较合理,*/ public static int COMMON_CUSTOMER_INTERVAL_TIME = 1; }
相关文章推荐
- 银行业务调度系统-心得2-项目源码即注释
- 银行业务调度系统-心得1-项目需求分析和类图架构
- 银行业务调度系统-心得1-项目需求分析和类图架构
- 交通灯管理系统-心得2-项目源码及注释.doc
- 交通灯管理系统-心得2-项目源码及注释.doc
- 面试项目<二>_银行业务调度系统
- 黑马程序员-Java项目之银行业务调度系统
- 黑马程序员——java面试中常遇到的面试项目——银行业务调度系统
- 项目——银行业务调度系统
- 黑马程序员--7K项目--银行业务调度系统
- 黑马程序员--java基础项目:银行业务调度系统
- 银行业务调度系统的项目
- 经典面试项目—银行业务调度系统
- java面试项目<银行业务调度系统>
- [项目]银行业务调度系统
- 黑马程序员 面试题项目--银行业务调度系统
- 银行业务调度系统 项目
- 银行业务调度系统心得
- Java基础(十七)——项目实战——银行业务调度系统
- JAVA简单项目"购物系统"的整个开发过程详解(内含源码和注释)