------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
模拟实现银行业务调度系统逻辑,具体需求如下:
1. 银行内有6个业务窗口,1 - 4号窗口为普通窗口,5号窗口为快速窗口,6号窗口为VIP窗口。
2.有三种对应类型的客户:VIP客户,普通客户,快速客户(办理如交水电费、电话费之类业务的客户)。
3.异步随机生成各种类型的客户,生成各类型用户的概率比例为:
VIP客户 :普通客户 :快速客户 = 1 :6 :3。
4.业务所需时间为最小值(提示:办理业务的过程可通过线程Sleep的方式模拟)。
5.各类型客户在其对应窗口按顺序依次办理业务。
1. 银行内有6个业务窗口,1 - 4号窗口为普通窗口,5号窗口为快速窗口,6号窗口为VIP窗口。
2.有三种对应类型的客户:VIP客户,普通客户,快速客户(办理如交水电费、电话费之类业务的客户)。
3.异步随机生成各种类型的客户,生成各类型用户的概率比例为:
VIP客户 :普通客户 :快速客户 = 1 :6 :3。
4.业务所需时间为最小值(提示:办理业务的过程可通过线程Sleep的方式模拟)。
5.各类型客户在其对应窗口按顺序依次办理业务。
6.当VIP(6号)窗口和快速业务(5号)窗口没有客户等待办理业务的时候,这两个窗口可以处理普通客户的业务,而一旦有对应的客户等待办理业务的时候,则优先处理对应客户的业务。
7.随机生成客户时间间隔以及业务办理时间最大值和最小值自定,可以设置。
7.随机生成客户时间间隔以及业务办理时间最大值和最小值自定,可以设置。
简而言之,银行调度管理系统,号码机,客户,和服务窗口三大元素组成:
1.号码机是生成号码,销毁号码的工具;
2.客户随机到来,用号码机生成号码;
3.服务窗口对来的客户号码依次进行处理,用号码机销毁号码。
又由于有三种客户,对应三种窗口,所以服务窗口可以定义成类,具体窗口由其实例化对象
首先号码的生成和销毁在同一个函数中,用List集合来存储,销毁就相当于取走,通过先生成先取走的队列方式,也可以用LinkList来完成。
<span style="font-size:14px;">public class NumberManager {
private int lastNumber = 1;
private List<Integer> queueNumbers = new ArrayList<Integer>();
public synchronized Int generateNewNumber(){
queueNumbers.add(lastNumber);
return lastNumber++;
}
public synchronized Int fetchNumber(){
if(queueNumbers.size()>0){
return (Integer)queueNumbers.remove(0);
}else{
return null;
}
}
}
</span>
<span style="font-size:14px;">public class NumberMachine {
private NumberMachine(){}
private static NumberMachine instance = new NumberMachine();
public static NumberMachine getInstance(){
return instance;
}
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;
}
}</span>
生成号码,即客户取号,以普通客户为例:
<span style="font-size:14px;"> Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){
public void run(){
Integer serviceNumber = NumberMachine.getInstance().getCommonManager().generateNewNumber();
System.out.println("第" + serviceNumber + "号普通客户正在等待服务!");
}
},
0,
Constants.COMMON_CUSTOMER_INTERVAL_TIME,
TimeUnit.SECONDS);</span>
销毁号码,即服务窗口的职能,以普通窗口为例:
<span style="font-size:14px;"> private void commonService(){
String windowName = "第" + number + "号" + type + "窗口";
System.out.println("正在获取任务...");
Integer serviceNumber = NumberMachine.getInstance().getCommonManager().fetchNumber();
if(serviceNumber != null ){
System.out.println(windowName + "开始为第" + serviceNumber + "号普通客户服务");
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 + "号普通客户服务,总共耗时" + serviceTime/1000 + "秒");
}else{
System.out.println(windowName + "没有取到普通任务,正在空闲一秒");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
</span>
当特殊窗口空闲时,可以作为普通窗口使用,只需要执行任务时判断是否空闲,如果空闲则调用普通窗口的方法即可。
如果是真实的系统,客户部分只需要提供接口即可,模拟系统则需要对客户的行为进行模拟,客户生成号码,窗口销毁号码。
银行系统各个窗口运行是独立的,相当于多个线程同时运行,但是相同类型的客户生成的号码确是连续的,所以在多线程并发执行的基础上又用了单例模式用来限制某些需要共享方法和数据所属的对象的创建。