模拟实现银行业务调度系统逻辑,具体需求如下:
VIP客户:普通客户:快速客户 = 1 :6 :3。
看了张老师的视频,听的希里糊涂的,用到了6个类,感觉自己跟不上思路,但是也了解了好多有用的东西。
我写的代码如下:
第一个类:取号机类
/** * 因为取号程序只有3个,所以设置为枚举对象 * * 取号程序应该有以下方法: * 1、产生号码的方法(客户拿号) * 2、获取号码的方法(窗口拿号) * 3、判断是否还有号码在排除 * * @author Administrator * */ import java.util.*; public enum NumberManager { VIP, COMMON, EXPRESS; // 三个取号程序 private List<Integer> numberList = new ArrayList<Integer>();// 用来保存生产的号码列表 private int number; private static final int generateTime = 5;// 生成普通号码的时间的最大值 private NumberManager() {// 启动一个线程用来不停地生产号码 new Thread(new Runnable() { public void run() { generateNumber(); } }).start(); } //------------------------1、产生号码的方法(客户拿号)--------------------------------------- public void generateNumber() { for (int i = 1; i < 501; i++) {// 假设每天只有500张排队号码纸 if (name().equals("COMMON")) // 如果是普通用户则1秒产生一个 try {Thread.sleep(1000);} catch (Exception e) {e.printStackTrace();} else if (name().equals("EXPRESS"))// 如果是快速用户则2~10秒产生一个 try {Thread.sleep((new Random().nextInt(generateTime) + 1)*1000*2);} catch (Exception e) { e.printStackTrace();} else // 如果是VIP用户则6~30秒产生一个 try {Thread.sleep((new Random().nextInt(generateTime) + 1)*1000*6);} catch (Exception e) { e.printStackTrace();} synchronized (COMMON) { numberList.add(++number); System.out.println(this + "客户 " + number + "号----------->正在等服务"); } } } //------------------------2、获取号码的方法(窗口拿号)--------------------------------------- public int getNumber() { return ((Integer) numberList.remove(0)).intValue();//拿到号码,并把号码从排除列表中移除 } //------------------------3、判断是否还有号码在排除------------------------------------------- public boolean hasNumber() { return !numberList.isEmpty(); } //------------------------重写toString方法--------------------------------------------------- public String toString(){ if(name().equals("COMMON")) return "普通"; else if(name().equals("EXPRESS")) return "快速"; else return "VIP"; } }
第二个类:服务窗口类
/** * 办理业务窗口应该有的方法: * 1、判断自己是否在为客户办理业务 * 2、判断4个普通窗口是否同时都在为客户办理业务 * 3、去问号码管理器取号,并为对应号码的客户办理业务 * 4、因为普通窗口有4个,它们处理的都是同样的数据(普通号码)所以,普通窗口取号的代码要进行同步处理 * 5、因为6个窗口都有处理普通号码的功能,所以可以把处理普通号码的代码单独写成一个方法,以便复用 * @author Administrator * */ import java.util.Random; import java.util.concurrent.*; public enum ServiceWindows { COMMON1, COMMON2, COMMON3, COMMON4, EXPRESS, VIP;//6个办理业务窗口 private boolean ServiceState;// 指示当前窗口是否在为客户办理业务的状态 private ServiceWindows() { ExecutorService pool = Executors.newSingleThreadExecutor(); pool.execute(new Runnable(){ //启动一个线程,给拿到号的顾客办理业务 public void run(){ while(true){ getNumber(); }}}); } //----------------------1、判断自己是否在为客户办理业务 -------------------------------- public boolean isServing(){ return ServiceState; } //----------------------2、判断4个普通窗口是否同时都在为客户办理业务------------------------- public boolean isCommonsServing() { return COMMON1.isServing()&&COMMON2.isServing()&&COMMON3.isServing()&&COMMON4.isServing(); } //-------------------3、办理业务的动作-------------------------------------------------- public void serving(NumberManager numManager,int num,int randomTime){ System.out.println(this+"窗口正在为"+numManager+"客户 "+num+"号 办理业务" ); long startTime = System.currentTimeMillis(); try{Thread.sleep((new Random().nextInt(randomTime)+1)*1000);}catch(Exception e){e.printStackTrace();} long usedTime = (System.currentTimeMillis()-startTime)/1000; System.out.println(this+"窗口已为"+numManager+"客户 "+num+"号 办理完业务,用时"+usedTime+"秒"); ServiceState = false;//服务状态为假 } //-------------------4、 为普通客户服务的方法 ------------------------------------------- public void serveForCommon(){ int num = 0; NumberManager numManager = null; synchronized(NumberManager.COMMON){ numManager = NumberManager.COMMON;//获取普通号码管理器 if(numManager.hasNumber()){ //--------------------------->必须同步的代码 num = numManager.getNumber();//向号码管理器取号------->必须同步的代码 ServiceState = true;//服务状态为正真 } } if(ServiceState){ serving(numManager, num, 10);//参数10指定服务时间为1~10秒 }else { System.out.println(this+"窗口空闲中"); try{Thread.sleep(1000);}catch(Exception e){e.printStackTrace();}//如果没人排除则休息1秒再去看有没有人排队 } } //----------------------5、去问号码管理器取号,并为对应号码的客户办理业务------------------- public void getNumber() { long startTime = 0; long usedTime = 0; //如果窗口为4个普通窗口的任意一个,则他们取的号码都是普通号码 if(name().equals("COMMON1")||name().equals("COMMON2")||name().equals("COMMON3")||name().equals("COMMON4")) { serveForCommon(); }else if(name().equals("EXPRESS")){ //如果窗口是快速窗口 NumberManager numManager = NumberManager.EXPRESS; //获取快速号码管理器 if(numManager.hasNumber()){ int num = numManager.getNumber();//取号 serving(numManager, num, 1);//参数10指定服务时间为1秒 }else { //如果没有快速客户 if(isCommonsServing())//如果普通窗口都在忙,则帮忙处理普通客户 serveForCommon(); else { System.out.println(this+"窗口空闲中"); try{Thread.sleep(1000);}catch(Exception e){e.printStackTrace();}//如果没人排除则休息1秒再去看有没有人排队 } } }else{ //如果窗口是VIP窗口 NumberManager numManager = NumberManager.VIP; //获取VIP号码管理器 if(numManager.hasNumber()){ int num = numManager.getNumber(); //取号 serving(numManager, num, 10);//参数10指定服务时间为1~10秒 }else { //如果没有VIP客户 if(isCommonsServing())//如果普通窗口都在忙,则帮忙处理普通客户 serveForCommon(); else { System.out.println(this+"窗口空闲中"); try{Thread.sleep(1000);}catch(Exception e){e.printStackTrace();}//如果没人排除则休息1秒再去看有没有人排队 } } } } //---------------------重写toString--------------------------------------------------------- public String toString(){ if(name().equals("VIP")) return "VIP"; else if(name().equals("EXPRESS")) return "快速"; else if(name().equals("COMMON1")) return "普通1号"; else if(name().equals("COMMON2")) return "普通2号"; else if(name().equals("COMMON3")) return "普通3号"; return "普通4号"; } }
第三个类:运行类
public class MainClass { public static void main(String[] args) { NumberManager num = NumberManager.COMMON; ServiceWindows window = ServiceWindows.COMMON1; } }
截一断我的运行结果,如下:
普通1号窗口空闲中
快速窗口空闲中
普通4号窗口空闲中
普通3号窗口空闲中
普通2号窗口空闲中
VIP窗口空闲中
普通客户 1号----------->正在等服务
快速窗口空闲中
普通1号窗口正在为普通客户 1号 办理业务
普通4号窗口空闲中
普通2号窗口空闲中
普通3号窗口空闲中
VIP窗口空闲中
普通客户 2号----------->正在等服务
快速窗口空闲中
普通4号窗口正在为普通客户 2号 办理业务
普通2号窗口空闲中
普通3号窗口空闲中
VIP窗口空闲中
普通客户 3号----------->正在等服务
快速窗口空闲中
普通2号窗口空闲中
普通3号窗口正在为普通客户 3号 办理业务
VIP窗口空闲中
普通客户 4号----------->正在等服务
快速窗口空闲中
普通2号窗口正在为普通客户 4号 办理业务
VIP窗口空闲中
普通客户 5号----------->正在等服务
快速窗口正在为普通客户 5号 办理业务
VIP窗口空闲中
VIP客户 1号----------->正在等服务
普通客户 6号----------->正在等服务
VIP窗口正在为VIP客户 1号 办理业务
普通客户 7号----------->正在等服务
普通4号窗口已为普通客户 2号 办理完业务,用时5秒
普通4号窗口正在为普通客户 6号 办理业务
VIP窗口已为VIP客户 1号 办理完业务,用时1秒
VIP窗口正在为普通客户 7号 办理业务
普通客户 8号----------->正在等服务
快速窗口已为普通客户 5号 办理完业务,用时3秒
快速窗口正在为普通客户 8号 办理业务