银行业务调度系统

来源:互联网 发布:课程录制软件 编辑:程序博客网 时间:2024/06/05 00:29

项目需求

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

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

2.有三种对应类型的客户:VIP客户,普通客户,快速客户

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

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

4.客户办理业务所需时间有最大值和最小值,在该范围内随机设定每个VIP客户以及普通客户办理业务所需的时间,快速客户办理业务所需时间为最小值

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

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

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

面向对象分析与设计

有三种客户:VIP客户、普通客户、快速客户,异步随机生成各种类型的客户,各种类型的客户在其对应的窗口按顺序依次办理业务。

应该有一个号码管理器对象,让这个对象产生号码,就等于随机生成了客户。有三类客户,所以要有三个号码管理器,统一由一个号码机器管理,这个号码机器始终只有一个。

各类型客户在其对应窗口按顺序依次办理业务,准确的说,应该是窗口依次叫号。

服务窗口每次找号码管理器获取当前要被服务的号码。

根据上面的分析,画UML类图如下:


编写NumberManager类

NumberManager类代码如下:

import java.util.ArrayList;import java.util.List;public class NumberManager {private int lastNumber=1;private List<Integer> queueNumber=new ArrayList<Integer>();//当客户来银行后,要取一个新号,则用此方法取public synchronized int generateNewNumber(){queueNumber.add(lastNumber);return lastNumber++;}//当服务台处理业务要叫号,就用此方法来叫public synchronized Integer fetchNumber(){Integer number=null;if (queueNumber.size()>0) {number=queueNumber.remove(0);}return number;}}

编写NumberMachine类

NumberMachine类代码如下:

public class NumberMachine {private NumberManager commonManager=new NumberManager();private NumberManager vipManager=new NumberManager();private NumberManager ExpressManager=new NumberManager();private static NumberMachine instance=new NumberMachine();public NumberManager getCommonManager() {return commonManager;}public NumberManager getVipManager() {return vipManager;}public NumberManager getExpressManager() {return ExpressManager;} private NumberMachine(){}public static NumberMachine getInstance(){return instance;}}

编写ServiceWindow类

ServiceWindow类代码如下:

import java.util.Random;import java.util.concurrent.Executors;public class ServiceWindow {private int windowId=1;private WindowType type=WindowType.Common;public void setWindowId(int windowId) {this.windowId = windowId;}public void setType(WindowType type) {this.type = type;}public void start(){  Executors.newSingleThreadExecutor().execute(new Runnable() {public void run() {switch (type) {case Common:commonService();break;case Express:expressService();break;case VIP:vipService();break;}}private void vipService() {String windowName="第"+windowId+"号"+type+"窗口";System.out.println(windowName+"正在获取任务");Integer number=NumberMachine.getInstance().getVipManager().fetchNumber();if (number!=null) {long beginTime=System.currentTimeMillis();int random=Constants.MAX_SERVICETIME-Constants.MIN_SERVICETIME;long serviceTime=new Random().nextInt(random)+Constants.MIN_SERVICETIME;try {Thread.sleep(serviceTime);} catch (Exception e) {}long costTime=System.currentTimeMillis()-beginTime;System.out.println(windowName+"为第"+number+"个"+type+"客户完成服务,耗时"+costTime/1000+"秒");}else {System.out.println(windowName+"没有取到任务!");commonService();}}private void expressService() {String windowName="第"+windowId+"号"+type+"窗口";System.out.println(windowName+"正在获取任务");Integer number=NumberMachine.getInstance().getExpressManager().fetchNumber();if (number!=null) {long beginTime=System.currentTimeMillis();try{Thread.sleep(Constants.MIN_SERVICETIME);}catch(Exception e){}long costTime=System.currentTimeMillis()-beginTime;System.out.println(windowName+"为第"+number+"个"+type+"客户完成服务,耗时"+costTime/1000+"秒");}else {System.out.println("没有取到任务");System.out.println(windowName+"没有取到任务!");commonService();}}private void commonService() {String windowName="第"+windowId+"号"+type+"窗口";System.out.println(windowName+"正在获取任务");Integer number=NumberMachine.getInstance().getCommonManager().fetchNumber();if (number!=null) {long beginTime=System.currentTimeMillis();int random=Constants.MAX_SERVICETIME-Constants.MIN_SERVICETIME;long serviceTime=new Random().nextInt(random)+Constants.MIN_SERVICETIME;try{Thread.sleep(serviceTime);}catch(Exception e){}long costTime=System.currentTimeMillis()-beginTime;System.out.println(windowName+"为第"+number+"个"+type+"客户完成服务,耗时"+costTime/1000+"秒");}else {System.out.println("没有取到任务");try{Thread.sleep(1000);}catch(Exception e){}}}});}}

ServiceWindow类中用了一个枚举WindowType代码如下:

public enum WindowType {Common,Express,VIP;public String toString(){switch (this) {case Common:return "普通";case Express:return "快速";default:return "VIP";}}}
ServiceWindow类中用了Constants类,专门装常量的类,代码如下:

public class Constants {public static int MAX_SERVICETIME=10000;public static int MIN_SERVICETIME=1000;}

编写按时生成客户的代码

在主函数中按时生成客户,客户比例是VIP客户:普通客户:快速客户=1:6:3,产生这些客户的时间间隔比例就是普通客户:快速客户:VIP客户=1:2:6,代码如下:

import java.util.concurrent.Executors;import java.util.concurrent.TimeUnit;public class MainClass {public static void main(String[] args) {//创建银行的6个服务窗口for (int i = 1; i <5; i++) {ServiceWindow commonWindow=new ServiceWindow();commonWindow.setWindowId(i);commonWindow.setType(WindowType.Common);commonWindow.start();}ServiceWindow expressWindow=new ServiceWindow();expressWindow.setWindowId(5);expressWindow.setType(WindowType.Express);expressWindow.start();ServiceWindow vipWindow=new ServiceWindow();vipWindow.setWindowId(6);vipWindow.setType(WindowType.VIP);vipWindow.start();//按需求生成普通客户Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {public void run() {Integer number=NumberMachine.getInstance().getCommonManager().generateNewNumber();System.out.println("第"+number+"号普通客户等待服务!");}}, 1, 1, TimeUnit.SECONDS);//按需求生成快速客户Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {public void run() {Integer number=NumberMachine.getInstance().getCommonManager().generateNewNumber();System.out.println("第"+number+"号快速客户等待服务!");}}, 1, 2, TimeUnit.SECONDS);//按需求生成VIP客户Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {public void run() {Integer number=NumberMachine.getInstance().getCommonManager().generateNewNumber();System.out.println("第"+number+"号VIP客户等待服务!");}}, 1, 6, TimeUnit.SECONDS);}}

总成测试和Bug修复

第一次运行程序,结果如下:

第1号普通窗口正在获取任务第5号快速窗口正在获取任务第4号普通窗口正在获取任务第3号普通窗口正在获取任务第2号普通窗口正在获取任务第6号VIP窗口正在获取任务没有取到任务第6号VIP窗口没有取到任务!没有取到任务没有取到任务没有取到任务

“没有取到任务”没有说明是哪个窗口没有取到任务,所以修改ServiceWindow类代码,然后再运行代码:

第2号普通窗口正在获取任务第2号普通窗口没有取到任务第8号普通客户等待服务!第4号普通窗口为第3个普通客户完成服务,耗时5秒第4号普通窗口正在获取任务第2号普通窗口正在获取任务第2号普通窗口没有取到任务第5号快速客户等待服务!第9号普通客户等待服务!第5号快速窗口为第1个快速客户完成服务,耗时8秒第5号快速窗口正在获取任务第2号普通窗口正在获取任务第10号普通客户等待服务!第6号VIP窗口为第1个VIP客户完成服务,耗时8秒第6号VIP窗口正在获取任务第5号快速窗口为第1个快速客户完成服务,耗时1秒第5号快速窗口正在获取任务
没有VIP窗口为普通用户服务,再检查ServiceWindow代码,寻找问题,原来是打印客户时使用了type变量,造成为普通客户服务时,还是显示VIP客户,所以修改代码,再运行:

第2号普通窗口正在获取任务第6号VIP窗口正在获取任务第5号快速窗口正在获取任务第1号普通窗口正在获取任务第3号普通窗口正在获取任务第4号普通窗口正在获取任务第6号VIP窗口没有取到任务,转到为普通客户服务第2号普通窗口没有取到任务,休息1秒第3号普通窗口没有取到任务,休息1秒第4号普通窗口没有取到任务,休息1秒第5号快速窗口没有取到任务,转到为普通客户服务第1号普通窗口没有取到任务,休息1秒第5号快速窗口正在获取任务
前几条都没有客户,客户来的太晚,于是把客户调早些来,运行结果如下:

第1号快速客户等待服务!第1号普通客户等待服务!第1号VIP客户等待服务!第1号普通窗口正在获取任务第2号普通窗口正在获取任务第3号普通窗口正在获取任务第2号普通窗口没有取到任务,休息1秒第4号普通窗口正在获取任务第3号普通窗口没有取到任务,休息1秒第4号普通窗口没有取到任务,休息1秒第5号快速窗口正在获取任务第6号VIP窗口正在获取任务第2号普通客户等待服务!第2号普通窗口正在获取任务第5号快速窗口为第1个快速客户完成服务,耗时1秒第5号快速窗口正在获取任务第5号快速窗口没有取到任务,转到为普通客户服务第5号快速窗口正在获取任务第5号快速窗口没有取到任务,休息1秒第4号普通窗口正在获取任务第4号普通窗口没有取到任务,休息1秒第3号普通窗口正在获取任务第3号普通窗口没有取到任务,休息1秒第3号普通客户等待服务!第2号快速客户等待服务!第5号快速窗口正在获取任务第3号普通窗口正在获取任务第3号普通窗口没有取到任务,休息1秒第4号普通窗口正在获取任务第4号普通客户等待服务!第3号普通窗口正在获取任务第5号快速窗口为第2个快速客户完成服务,耗时1秒第5号快速窗口正在获取任务第5号快速窗口没有取到任务,转到为普通客户服务第5号快速窗口正在获取任务第5号快速窗口没有取到任务,休息1秒第6号VIP窗口为第1个VIP客户完成服务,耗时3秒第6号VIP窗口正在获取任务第6号VIP窗口没有取到任务,转到为普通客户服务第6号VIP窗口正在获取任务第6号VIP窗口没有取到任务,休息1秒第5号普通客户等待服务!第3号快速客户等待服务!第5号快速窗口正在获取任务第6号VIP窗口正在获取任务第6号VIP窗口没有取到任务,转到为普通客户服务第6号VIP窗口正在获取任务第6号普通客户等待服务!第5号快速窗口为第3个快速客户完成服务,耗时1秒第5号快速窗口正在获取任务第5号快速窗口没有取到任务,转到为普通客户服务第5号快速窗口正在获取任务第7号普通客户等待服务!第2号VIP客户等待服务!第4号快速客户等待服务!第3号普通窗口为第4个普通客户完成服务,耗时3秒第3号普通窗口正在获取任务第2号普通窗口为第2个普通客户完成服务,耗时5秒第2号普通窗口正在获取任务第2号普通窗口没有取到任务,休息1秒第1号普通窗口为第1个普通客户完成服务,耗时6秒第1号普通窗口正在获取任务第1号普通窗口没有取到任务,休息1秒第8号普通客户等待服务!第5号快速窗口为第6个普通客户完成服务,耗时2秒第5号快速窗口正在获取任务第2号普通窗口正在获取任务第1号普通窗口正在获取任务第1号普通窗口没有取到任务,休息1秒第9号普通客户等待服务!第5号快速客户等待服务!第5号快速窗口为第4个快速客户完成服务,耗时1秒第5号快速窗口正在获取任务第1号普通窗口正在获取任务第10号普通客户等待服务!第5号快速窗口为第5个快速客户完成服务,耗时1秒第5号快速窗口正在获取任务第5号快速窗口没有取到任务,转到为普通客户服务第5号快速窗口正在获取任务第4号普通窗口为第3个普通客户完成服务,耗时7秒第4号普通窗口正在获取任务第4号普通窗口没有取到任务,休息1秒第11号普通客户等待服务!第6号快速客户等待服务!第6号VIP窗口为第5个普通客户完成服务,耗时6秒第6号VIP窗口正在获取任务第4号普通窗口正在获取任务第12号普通客户等待服务!第6号VIP窗口为第2个VIP客户完成服务,耗时1秒第6号VIP窗口正在获取任务第6号VIP窗口没有取到任务,转到为普通客户服务第6号VIP窗口正在获取任务第13号普通客户等待服务!第7号快速客户等待服务!第3号VIP客户等待服务!第3号普通窗口为第7个普通客户完成服务,耗时6秒第3号普通窗口正在获取任务第14号普通客户等待服务!第15号普通客户等待服务!第8号快速客户等待服务!第16号普通客户等待服务!第2号普通窗口为第8个普通客户完成服务,耗时8秒第2号普通窗口正在获取任务
最终正确的代码如下:

ServiceWindow类:

import java.util.Random;import java.util.concurrent.Executors;public class ServiceWindow {private int windowId=1;private WindowType type=WindowType.Common;public void setWindowId(int windowId) {this.windowId = windowId;}public void setType(WindowType type) {this.type = type;}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 vipService() {String windowName="第"+windowId+"号VIP窗口";System.out.println(windowName+"正在获取任务");Integer number=NumberMachine.getInstance().getVipManager().fetchNumber();if (number!=null) {long beginTime=System.currentTimeMillis();int random=Constants.MAX_SERVICETIME-Constants.MIN_SERVICETIME;long serviceTime=new Random().nextInt(random)+Constants.MIN_SERVICETIME;try {Thread.sleep(serviceTime);} catch (Exception e) {}long costTime=System.currentTimeMillis()-beginTime;System.out.println(windowName+"为第"+number+"个VIP客户完成服务,耗时"+costTime/1000+"秒");}else {System.out.println(windowName+"没有取到任务,转到为普通客户服务");commonService();}}private void expressService() {String windowName="第"+windowId+"号快速窗口";System.out.println(windowName+"正在获取任务");Integer number=NumberMachine.getInstance().getExpressManager().fetchNumber();if (number!=null) {long beginTime=System.currentTimeMillis();try{Thread.sleep(Constants.MIN_SERVICETIME);}catch(Exception e){}long costTime=System.currentTimeMillis()-beginTime;System.out.println(windowName+"为第"+number+"个快速客户完成服务,耗时"+costTime/1000+"秒");}else {System.out.println(windowName+"没有取到任务,转到为普通客户服务");commonService();}}private void commonService() {String windowName="第"+windowId+"号"+type+"窗口";Integer number=NumberMachine.getInstance().getCommonManager().fetchNumber();System.out.println(windowName+"正在获取任务");if (number!=null) {long beginTime=System.currentTimeMillis();int random=Constants.MAX_SERVICETIME-Constants.MIN_SERVICETIME;long serviceTime=new Random().nextInt(random)+Constants.MIN_SERVICETIME;try{Thread.sleep(serviceTime);}catch(Exception e){}long costTime=System.currentTimeMillis()-beginTime;System.out.println(windowName+"为第"+number+"个普通客户完成服务,耗时"+costTime/1000+"秒");}else {System.out.println(windowName+"没有取到任务,休息1秒");try{Thread.sleep(1000);}catch(Exception e){}}}});}}
最终正确的MainClass类代码:

import java.util.concurrent.Executors;import java.util.concurrent.TimeUnit;public class MainClass {public static void main(String[] args) {//按需求生成普通客户Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {public void run() {Integer number=NumberMachine.getInstance().getCommonManager().generateNewNumber();System.out.println("第"+number+"号普通客户等待服务!");}}, 0, 1, TimeUnit.SECONDS);//按需求生成快速客户Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {public void run() {Integer number=NumberMachine.getInstance().getExpressManager().generateNewNumber();System.out.println("第"+number+"号快速客户等待服务!");}}, 0, 2, TimeUnit.SECONDS);//按需求生成VIP客户Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {public void run() {Integer number=NumberMachine.getInstance().getVipManager().generateNewNumber();System.out.println("第"+number+"号VIP客户等待服务!");}}, 0, 6, TimeUnit.SECONDS);//创建银行的6个服务窗口for (int i = 1; i <5; i++) {ServiceWindow commonWindow=new ServiceWindow();commonWindow.setWindowId(i);commonWindow.setType(WindowType.Common);commonWindow.start();}ServiceWindow expressWindow=new ServiceWindow();expressWindow.setWindowId(5);expressWindow.setType(WindowType.Express);expressWindow.start();ServiceWindow vipWindow=new ServiceWindow();vipWindow.setWindowId(6);vipWindow.setType(WindowType.VIP);vipWindow.start();}}
















0 0