------- android培训、java培训、期待与您交流! ----------
课题:银行业务调度系统
模拟实现银行业务调度系统逻辑,具体需求如下:
银行内有6个业务窗口,1 - 4号窗口为普通窗口,5号窗口为快速窗口,6号窗口为VIP窗口。
有三种对应类型的客户:VIP客户,普通客户,快速客户(办理如交水电费、电话费之类业务的客户)。
异步随机生成各种类型的客户,生成各类型用户的概率比例为:
VIP客户 :普通客户 :快速客户 = 1 :6 :3。
客户办理业务所需时间有最大值和最小值,在该范围内随机设定每个VIP客户以及普通客户办理业务所需的时间,快速客户办理业务所需时间为最小值(提示:办理业务的过程可通过线程Sleep的方式模拟)。
各类型客户在其对应窗口按顺序依次办理业务。
当VIP(6号)窗口和快速业务(5号)窗口没有客户等待办理业务的时候,这两个窗口可以处理普通客户的业务,而一旦有对应的客户等待办理业务的时候,则优先处理对应客户的业务。
随机生成客户时间间隔以及业务办理时间最大值和最小值自定,可以设置。
不要求实现GUI,只考虑系统逻辑实现,可通过Log方式展现程序运行结果。
总思考:
1,客户的多少,以及什么客户是根据号码管理器生成的什么类型的号,生成了多少来决定的,所以要有个类用于描述号码管理器。
2,有了号码管理器,但是银行里的叫号机是唯一的(单例),所以有个类用于描述叫号机,叫号机中是各个客户类型的号码管理器。
3,有了号码管理器和叫号机,还得有服务窗口,,,定义一个描述服务窗口的类,,服务窗口的类型也不同,有负责普通客户,快速客户,VIP客户。
4,测试类:随机生成号码,建立多个窗口开始服务。
号码管理器类:
思考:
1,有个私有的成员变量,int型,,,相当于号码管理器生成的号码。
2,有个获取该号码的方法,在获取号码过程中,每获取一个号码,就要将该号码存入集合中,,(叫号时要按照号码的顺序叫,也就是按照号码的顺序删除,所以用到集合)
3,定义功能,如果数组中有元素,就取出元素(相当于如果有没有被服务到的号码,就进行服务,,,,产生了客户,就要进行服务)
叫号机:
思考:
1,叫号机中有三种类型的号码管理器,,,普通,快速,VIP,,,,私有
2,可以获取这三种类型的号码管理器,,提供获取方法
3,叫号机是唯一的,单例,,,,,
服务窗口:
思考:
1,服务窗口都有窗口号
2,服务窗口都有各自对应的类型(普通,快速,VIP),,,,可以定义枚举类来获取对应的类型。
3,服务窗口可以根据自己是什么类型的窗口,提供针对该类型的客户的服务,,,,,服务的方法(因为该方法需要一直被某个对应的类型重复执行,
所以使用到了多线程)
4,服务过程中有服务的完成所需要的时间,,,快速的时间永远是最小的值,,,普通和VIP是随机最小值和最大值间的随机值。可以sleep(Random)完成。
其中要注意使用到多线程的地方和使用到锁(同步代码块)的地方
号码管理器的代码:
package com.itheima.test;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class NumberManager {
private int lastNumber;
private List<Integer> queueNumbers = new ArrayList<Integer>();
private Lock lock = new ReentrantLock();
public Integer generateNewNumber(){
lock.lock();
try{
queueNumbers.add(++lastNumber);
return lastNumber;
}finally{
lock.unlock();
}
}
public Integer fetchNumber(){
lock.lock();
try{
if(queueNumbers.size()>0){
return queueNumbers.remove(0);
}
return null;
}finally{
lock.unlock();
}
}
}
叫号机的代码:
package com.itheima.test;
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;
}
}
服务窗口代码:
package com.itheima.test;
import java.util.Random;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;
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 int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public void start(){
Executors.newSingleThreadExecutor().execute(new Runnable(){
@Override
public void run() {
switch(type){
case COMMON:
while(true){
commonService();
}
//break;
case EXPRESS:
while(true){
expressService();
}
//break;
case VIP:
while(true){
vipService();
}
//break;
}
}
});
}
private void commonService() {
// TODO Auto-generated method stub
Integer useNumber = NumberMachine.getInstance().getCommonManager().fetchNumber();
System.out.println(number + "号" + type + "窗口" + "正在叫号,,,,,,,,,,,,,,,,,,,叫号中");
if(useNumber!=null){
System.out.println(number + "号" + type + "窗口" + "正在为" + useNumber + "号普通顾客服务+++++++++++++++++++++++++++++++++++++++++++++++++++++++服务中(普通)");
long startTime = System.currentTimeMillis();
try {
Thread.sleep(new Random().nextInt(Constants.MAX_SERVICE_TIME-Constants.MIN_SERVICE_TIME) +1 +Constants.MIN_SERVICE_TIME);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
long serveiceTime = (System.currentTimeMillis() - startTime)/1000;
System.out.println(number + "号" + type + "窗口" + "为 "+ useNumber +" 号普通顾客服务完毕,耗时: " + serveiceTime +"秒~~~~~服务完毕(普通)");
}
else{
System.out.println("没有等待服务的普通客户,,,,,休息1秒,*****休息中(普通)");
try {
Thread.sleep(Constants.MIN_SERVICE_TIME);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private void expressService() {
// TODO Auto-generated method stub
Integer useNumber = NumberMachine.getInstance().getExpressManager().fetchNumber();
System.out.println(number + "号" + type + "窗口" + "正在叫号,,,,,,,,,,,,,,,,,,,叫号中");
if(useNumber!=null){
System.out.println(number + "号" + type + "窗口" + "正在为" + useNumber + "号" + type + "顾客服务+++++++++++++++++++++++++++++++++++++++++++++++++++++++服务中 "+ type);
long startTime = System.currentTimeMillis();
try {
Thread.sleep(new Random().nextInt(Constants.MAX_SERVICE_TIME-Constants.MIN_SERVICE_TIME) +1 +Constants.MIN_SERVICE_TIME);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
long serveiceTime = (System.currentTimeMillis() - startTime)/1000;
System.out.println(number + "号" + type + "窗口" + "为 "+ useNumber +" 号" + type + "服务完毕,耗时: " + serveiceTime +"秒~~~~~服务完毕"+ type);
}
else{
System.out.println("没有等待服务的" + type + "客户,开始叫普通号,看有没有等待的客户,,,,,,,,,,,,,,,,,,,叫号中");
commonService();
}
}
private void vipService() {
// TODO Auto-generated method stub
Integer useNumber = NumberMachine.getInstance().getVipManager().fetchNumber();
System.out.println(number + "号" + type + "窗口" + "正在叫号,,,,,,,,,,,,,,,,,,,叫号中");
if(useNumber!=null){
System.out.println(number + "号" + type + "窗口" + "正在为" + useNumber + "号" + type + "顾客服务+++++++++++++++++++++++++++++++++++++++++++++++++++++++服务中 "+ type);
long startTime = System.currentTimeMillis();
try {
Thread.sleep(new Random().nextInt(Constants.MAX_SERVICE_TIME-Constants.MIN_SERVICE_TIME) +1 +Constants.MIN_SERVICE_TIME);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
long serveiceTime = (System.currentTimeMillis() - startTime)/1000;
System.out.println(number + "号" + type + "窗口" + "为 "+ useNumber +" 号" + type + "服务完毕,耗时: " + serveiceTime +"秒~~~~~服务完毕"+ type);
}
else{
System.out.println("没有等待服务的" + type + "客户,开始叫普通号,看有没有等待的客户,,,,,,,,,,,,,,,,,,,叫号中");
commonService();
}
}
}
使用到的枚举类和静态常量类的代码:
枚举类:
package com.itheima.test;
public enum CustomerType {
COMMON,EXPRESS,VIP;
public String toString() {
switch(this){
case COMMON:{
return "普通";
}
case EXPRESS:{
return "快速";
}
case VIP:{
return "VIP";
}
}
return null;
}
}
静态常量类:
package com.itheima.test;
public class Constants {
public static final int MAX_SERVICE_TIME = 10000;
public static final int MIN_SERVICE_TIME = 1000;
/*每个普通窗口服务一个客户的平均时间为5秒,一共有4个这样的窗口,也就是说银行的所有普通窗口合起来
* 平均1.25秒内可以服务完一个普通客户,再加上快速窗口和VIP窗口也可以服务普通客户,所以,
* 1秒钟产生一个普通客户比较合理,*/
public static final int COMMON_CUSTOMER_INTERVAL_TIME = 1;
}
如果全部理解了的话比交通灯的要容易,,,,如果对银行业务不熟悉,不了解运作的话,比较费力气。。。。看张老师的视频的时候要紧跟着思想走,不然很容易犯晕。