银行业务调度系统回顾
------- android培训、java培训、期待与您交流! ----------
public class NumberManager {
private int lastNumer = 1;
private List<Integer> queue = new ArrayList<Integer>();
/**
* 号码管理器它有两个方法 一个是生成号码,供客户端取号获取服务使用 一个是供服务窗口取号使用,这个是该为哪个号码提供服务
*/
public synchronized Integer genrateNewNumber() {
// 把产生的号码添加到集合中
queue.add(lastNumer);
return lastNumer++; // 产生号码,第一次产生1,第二次产生2
}
public synchronized Integer feathNumber() {
// 服务窗口要获取到该为哪个号码服务
// 号码是从哪里取来的了?
// 我们应该把生成的号码以队列的方式存储到集合中,然后服务窗口在取号的时候
// 是从集合的0位置开始取的
Integer number=null;
if(queue.size()>0){
number= queue.remove(0);
}
return number;
}
//多个方法操作同一个变量的时候,多个方法要做成同步的。让它们互斥
}
/**
* 号码机器 它里面管理着三个号码管理器 在类中创建三个号码管理器的对象并且返回三个获取这三个号码管理器的方法
*/
public class NumberMachine {
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;
}
// 因为号码机器在当前的系统中只有一个
// 所以我们需要把它给做成单例的
private NumberMachine() {
}
public static NumberMachine getInstance() {
return instance;
}
// 别人不能创建对象但是可以通过我们提供的静态的方法来获得我们 的这个类的内部创建的这个对象
// 这个对象会在这个类还没有调用之前就已经创建好的
private static NumberMachine instance = new NumberMachine();
}
public class ServiceWindow {
/**
* 服务窗口
*/
// 假设默认的服务的窗口是普通的类型
private CustomerType type = CustomerType.COMMON;
private int windowId=1; //窗口的编号,因为普通窗口有多个
public void setType(CustomerType type) {
this.type = type;
}
public void setWindowId(int windowId) {
this.windowId = windowId;
}
// 我们有三种不同类型的服务窗口:普通,快速,VIP
// 这里有一个开始服务的方法
public void start() {
// 因为从号码机那里获得要服务的号码是耗时的操作所以要单独使用一个线程来执行操作
Executors.newSingleThreadExecutor().execute(new Runnable() {
@Override
public void run() {
while (true) { // 不停的取号
switch (type) {
case COMMON:
commonService();
break;
case EXPRESS:
expressService();
break;
case VIP:
vipService();
break;
}
}
}
});
}
//普通服务窗口
private void commonService() {
String windowName="第"+windowId+"个"+type+"窗口";
//我们这里该找哪个号码管理器取号了?
//这个要看我们的当前的服务窗口是哪种?然后找对应的号码管理器
//因为只有三种所以我们使用枚举来进行操作
Integer number=NumberMachine.getInstance().getCommonManager().feathNumber();
System.out.println(windowName+"开始获取普通服务");
//这里使用int类型接收会有问题。因为集合中存储的是integer类型。如果没有数据返回的是空.
//所以我们要对这里进行修改
if(number!=null){
//如果获取到了要服务的号码
//则执行服务
System.out.println(windowName+"开始为第"+number+"个普通客户服务");
//计算为用户服务的时间
long beginTime=System.currentTimeMillis();
int maxRandom=Constants.MAX_SERVICE_TIME-Constants.MIN_SERVICE_TIME;
long serviceTime=new Random().nextInt(maxRandom)+1+Constants.MIN_SERVICE_TIME;
//模拟窗口为用户提供服务
try {
Thread.sleep(serviceTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
long coastTime=System.currentTimeMillis()-beginTime;
System.out.println(windowName+"为第"+number+"个普通客户完成服务,耗时"+coastTime/1000+"秒");
}else{
System.out.println(windowName+"没有获取到普通服务,要休息1秒");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
快速服务窗口
private void expressService() {
String windowName="第"+windowId+"个"+type+"窗口";
//我们这里该找哪个号码管理器取号了?
//这个要看我们的当前的服务窗口是哪种?然后找对应的号码管理器
//因为只有三种所以我们使用枚举来进行操作
Integer number=NumberMachine.getInstance().getExpressManager().feathNumber();
System.out.println(windowName+"开始获取快速业务");
//这里使用int类型接收会有问题。因为集合中存储的是integer类型。如果没有数据返回的是空.
//所以我们要对这里进行修改
if(number!=null){
//如果获取到了要服务的号码
//则执行服务
System.out.println(windowName+"开始为第"+number+"个快速客户服务");
//计算为用户服务的时间
long beginTime=System.currentTimeMillis();
// int maxRandom=Constants.MAX_SERVICE_TIME-Constants.MIN_SERVICE_TIME;
// long serviceTime=new Random().nextInt(maxRandom)+1+Constants.MIN_SERVICE_TIME;
//模拟窗口为用户提供服务
try {
Thread.sleep(Constants.MIN_SERVICE_TIME);
} catch (InterruptedException e) {
e.printStackTrace();
}
long coastTime=System.currentTimeMillis()-beginTime;
System.out.println(windowName+"为第"+number+"个"+type+"客户提供服务耗时"+coastTime/1000+"秒");
}else{
System.out.println(windowName+"没有获取到快速业务,可以为普通客户提供服务");
//没有获取到快速业务需要为普通客户提供服务
commonService();
}
}
//VIP服务窗口
private void vipService() {
String windowName="第"+windowId+"个"+type+"窗口";
//我们这里该找哪个号码管理器取号了?
//这个要看我们的当前的服务窗口是哪种?然后找对应的号码管理器
//因为只有三种所以我们使用枚举来进行操作
Integer number=NumberMachine.getInstance().getVipManager().feathNumber();
System.out.println(windowName+"正在获取VIP业务");
//这里使用int类型接收会有问题。因为集合中存储的是integer类型。如果没有数据返回的是空.
//所以我们要对这里进行修改
if(number!=null){
//如果获取到了要服务的号码
//则执行服务
System.out.println(windowName+"开始为第"+number+"个VIP客户服务");
//计算为用户服务的时间
long beginTime=System.currentTimeMillis();
int maxRandom=Constants.MAX_SERVICE_TIME-Constants.MIN_SERVICE_TIME;
long serviceTime=new Random().nextInt(maxRandom)+1+Constants.MIN_SERVICE_TIME;
//模拟窗口为用户提供服务
try {
Thread.sleep(serviceTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
long coastTime=System.currentTimeMillis()-beginTime;
System.out.println(windowName+"为第"+number+"个"+type+"客户提供服务耗时"+coastTime/1000+"秒");
}else{
System.out.println(windowName+"没有获取到VIP业务,可以为普通客户提供服务");
//没有获取到快速业务需要为普通客户提供服务
commonService();
}
}
}
//顾客的类型
public enum CustomerType {
COMMON, EXPRESS, VIP;
public String toString() {
switch (this) {
case COMMON:
return "普通";
case EXPRESS:
return "快速";
case VIP:
return name();
}
return null;
}
}
public class Constants {
public static int MAX_SERVICE_TIME=10000;
public static int MIN_SERVICE_TIME=1000;
//间隔的时间
public static int COST_CONSTANTS_INTERVAL_TIME=1;
}
测试效果如下
6号快速客户等待服务...
第1个VIP窗口为第4个普通客户完成服务,耗时6秒
第1个VIP窗口正在获取VIP业务
第1个VIP窗口开始为第2个VIP客户服务
12号普通客户等待服务...
13号普通客户等待服务...
7号快速客户等待服务...
3号VIP客户等待服务...
14号普通客户等待服务...
第4个普通窗口为第6个普通客户完成服务,耗时7秒
第4个普通窗口开始获取普通服务
第4个普通窗口开始为第11个普通客户服务
第2个普通窗口为第7个普通客户完成服务,耗时7秒
第2个普通窗口开始获取普通服务
第2个普通窗口开始为第12个普通客户服务
15号普通客户等待服务...
8号快速客户等待服务...
16号普通客户等待服务...
第3个普通窗口为第9个普通客户完成服务,耗时6秒
第3个普通窗口开始获取普通服务
第3个普通窗口开始为第13个普通客户服务
第1个普通窗口为第8个普通客户完成服务,耗时7秒
第1个普通窗口开始获取普通服务
第1个普通窗口开始为第14个普通客户服务
第1个快速窗口为第10个普通客户完成服务,耗时5秒