------- android培训、java培训、期待与您交流! ----------
银行业务调度系统的总结:
1,对象有客户、号码、业务窗口
2,客户是根据号码来区分的,一个客户对应一个号码。号码有贵宾、普通和快速三种区分。所以要产生三个号码管理器对象,各自管理一类用户的排队号码。这三个号码管理器对象统一由一个号码机器进行管理,这个号码机器在整个系统中始终只能有一个,所以,它要被设计成单例
3,业务窗口也是根据号码的三种区分,进行不同的服务。窗口分贵宾、普通和快速三种。不同的窗口分别为不同的客户服务。所以服务窗口类需要有窗口类别的属性,另外要有窗口的名称的属性。
4,业务窗口服务不断获取客户号码,一旦有客户等待,就获取到号码进行服务。
5,在主程序中,建立窗口的实例对象,调用start方法,启动线程服务,并产生客户。
6,整个系统就是由6个线程交替执行,即贵宾(1个)、普通(4个)和快速(1个)。
7,系统用到枚举类,如果想要输出自定义的信息,需要覆盖toString方法。
8,用到一个存放常量的类。编程过程中,使用到的常量最好统一进行定义为一个类中的静态常量。
根据"谁拥有数据,谁提供处理数据的方法"的原则进行分析:
客户拥有贵宾、普通、快速三种特性,所以客户应该提供生成三种客户的方法。但是客户其实是跟号码一一对应的,银行是根据号码来确定有没有客户的。所以提供生成三种客户方法的对象应该是号码。
号码还要提供获取下一个要服务的对象的方法和产生新号码的方法。
窗口拥有窗口ID、窗口类别(贵宾、普通和快速)的属性,还要有为客户服务的方法。
程序处理流程:
1,main方法中,创建三种类型服务窗口的对象,并调用对象的start方法,启动线程。
2,每个对象启动一个线程。线程中根据对象的类别(Type)不同,进行不同的服务(commonServie,vipService,expressService)。
3,普通客户服务(commonService)流程:
首先利用号码机获得普通客户的实例对象,然后调用号码管理类的fetchServiceNumber方法获取一个普通客户队列等待服务的号码。如果号码不为空,则开始服务,否则等待。
4,快速客户服务(expressService)流程:
首先利用号码机获得快速客户的实例对象,然后调用号码管理类的fetchServiceNumber方法获取一个快速客户队列等待服务的号码。如果号码不为空,则开始服务,否则进行普通客户服务。
5,VIP客户服务(vipService)流程:
首先利用号码机获得VIP客户的实例对象,然后调用号码管理类的fetchServiceNumber方法获取一个VIP客户队列等待服务的号码。如果号码不为空,则开始服务,否则进行普通客户服务。
源代码:
号码管理类:
package bank;
import java.util.ArrayList;
import java.util.List;
public class NumberManager {
private int lastNumber = 1;
//变量的类型尽量用超类
private List<Integer> queueNumber = new ArrayList<Integer>();
//多个线程访问同一个数据的时候,要互斥
public synchronized Integer generateNewManager(){
queueNumber.add(lastNumber);
return lastNumber++;
}
public synchronized Integer fetchServiceNumber(){
Integer number = null;
//队列有值才取号,否则报错
if(queueNumber.size()>0){
number = queueNumber.remove(0);
}
//取走集合中的值,这个方法有一个返回值,返回值就是取走的值
return number;
}
}
号码机:
package bank;
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();
}
业务窗口:
package bank;
import java.util.Random;
import java.util.concurrent.Executors;
public class ServiceWindow {
//使用set和get方法设置属性值,比较灵活;如果使用构造方法生成时赋值,那么不能进行改动
public void setType(CustomerType type) {
this.type = type;
}
public void setWindowId(int windowId) {
this.windowId = windowId;
}
//默认是普通窗口
private CustomerType type = CustomerType.COMMON;
private int windowId = 1;
public void start(){
//线程池执行任务,线程池在到池里去找一个空闲的线程去执行
Executors.newSingleThreadExecutor().execute(new Runnable(){
public void run() {
while(true){
//switch效率比if else高,switch的数据类型不能是long
switch(type){
case COMMON:
commonService();
break;
case VIP:
vipService();
break;
case EXPRESS:
expressService();
break;
}
// NumberMachine.getInstance();
}
}
});
}
private void commonService() {
String windowName = "第"+windowId+"号"+type+"窗口";
Integer number = NumberMachine.getInstance().getCommonManager().fetchServiceNumber();
System.out.println(windowName+"正在获取需要服务的号码");
if(number!=null){
System.out.println(windowName+"为第"+number+"个"+"普通"+"客户服务");
//开始服务的时间
long beginTime = System.currentTimeMillis();
//最大的服务时间
int maxRand = Constants.MAX_SERVICE_TIME-Constants.MIN_SERVICE_TIME;
//随机的服务时间,产生的随机数位0到8999之间的随机数,希望产生1-9000,所以再加1
long serviceTime=new Random().nextInt(maxRand)+1+Constants.MIN_SERVICE_TIME;
try {
Thread.sleep(serviceTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
//服务结束的时间
long endTime = System.currentTimeMillis();
//服务耗时
long costTime = endTime-beginTime;
System.out.println(windowName+"为第"+number+"个"+type+"客户完成服务,同时消耗时间为"+costTime);
}else{
System.out.println(windowName+"没有需要服务的号码,先休息一秒");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void expressService() {
String windowName = "第"+windowId+"号"+type+"窗口";
Integer number = NumberMachine.getInstance().getExpressManager().fetchServiceNumber();
System.out.println(windowName+"正在获取需要服务的号码");
if(number!=null){
System.out.println(windowName+"为第"+number+"个"+type+"客户服务");
long beginTime = System.currentTimeMillis();
try {
Thread.sleep(Constants.MIN_SERVICE_TIME);
} catch (InterruptedException e) {
e.printStackTrace();
}
long endTime = System.currentTimeMillis();
long costTime = endTime-beginTime;
System.out.println(windowName+"为第"+number+"个"+type+"客户完成服务,同时消耗时间为"+costTime);
}else{
System.out.println(windowName+"没有需要服务的号码,先休息一秒");
commonService();
}
}
//VIP服务
private void vipService() {
String windowName = "第"+windowId+"号"+type+"窗口";
Integer number = NumberMachine.getInstance().getVipManager().fetchServiceNumber();
System.out.println(windowName+"正在获取需要服务的号码");
if(number!=null){
System.out.println(windowName+"为第"+number+"个"+type+"客户服务");
long beginTime = System.currentTimeMillis();
//最大的服务时间
int maxRand = Constants.MAX_SERVICE_TIME-Constants.MIN_SERVICE_TIME;
//随机的服务时间,产生的随机数位0到8999之间的随机数,希望产生1-9000,所以再加1
long serviceTime=new Random().nextInt(maxRand)+1+Constants.MIN_SERVICE_TIME;
try {
Thread.sleep(serviceTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
long endTime = System.currentTimeMillis();
long costTime = endTime-beginTime;
System.out.println(windowName+"为第"+number+"个"+type+"客户完成服务,同时消耗时间为"+costTime);
}else{
System.out.println(windowName+"没有需要服务的号码,开始获取普通用户");
commonService();
}
}
}
客户类型,即号码类型:使用枚举
package bank;
public enum CustomerType {
COMMON,VIP,EXPRESS;
//type
public String toString(){
switch(this){
case COMMON:
return "普通";
case VIP:
return "贵宾";
case EXPRESS:
return "快速";
}
return null;
}
}
常量类:最大服务时间,最小服务时间,客户进来的频率
package bank;
public class Constants {
public static int MAX_SERVICE_TIME=10000;
public static int MIN_SERVICE_TIME= 1000;
public static int COMMON_CUSTOMER_INTERVAL_TIME = 1;
}
主程序:
package bank;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class mainClass {
/**
* @param args
*/
public static void main(String[] args) {
//4个普通窗口
for(int i = 1;i<5;i++){
ServiceWindow commonWindow = new ServiceWindow();
commonWindow.setWindowId(i);
commonWindow.start();
}
//贵宾窗口
ServiceWindow vipWindow = new ServiceWindow();
vipWindow.setType(CustomerType.VIP);
vipWindow.start();
//快速窗口
ServiceWindow expressWindow = new ServiceWindow();
expressWindow.setType(CustomerType.EXPRESS);
expressWindow.start();
//COMMON调度线程池,一秒钟增加一个普通客户
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){
public void run() {
Integer number = NumberMachine.getInstance().getCommonManager().generateNewManager();
System.out.println(number + "号普通客户等待服务!");
}
},
0,
Constants.COMMON_CUSTOMER_INTERVAL_TIME,
TimeUnit.SECONDS
);
//vip
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){
public void run() {
Integer number = NumberMachine.getInstance().getVipManager().generateNewManager();
System.out.println(number + "号VIP客户等待服务!");
}
},
0,
Constants.COMMON_CUSTOMER_INTERVAL_TIME * 6,
TimeUnit.SECONDS
);
//EXPRESS
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){
public void run() {
Integer number = NumberMachine.getInstance().getExpressManager().generateNewManager();
System.out.println(number + "号快速客户等待服务!");
}
},
0,
Constants.COMMON_CUSTOMER_INTERVAL_TIME * 2,
TimeUnit.SECONDS
);
}
}