------- android培训、java培训、期待与您交流! ----------
面向对象分析:
1,银行的每一个客户其实就是由银行的取号机产生的号码来表示的,所以应该有一个取号机对象,这个对象产生号码,相当于生成了客户。而这三类客户(VIP、普通和快速)都是由这一台机器产生的,因此这个机器始终只有一个,应设计成单例。
2,3类客户要在不同的窗口办理不同的业务,需要有三类客户对象,也需要有三类窗口来为其服务。
3,VIP窗口和快速窗口可以办理普通客户,但会优先办理自己的客户,所以需要在VIP窗口和快速窗口中,判断如果没有自己的客户,就调用普通窗口的服务方法。
类的编写:
号码管理器类NumberManager:
public class numberManager{
private int lastNumber = 1;
private List<Integer> queueNumber = new ArrayList<Integer>();//创建一个号码队列List
public synchronized Integer generateNewManager(){//产生用户号码,由于与fetchServiceNumber是两个不同线程操作同一个数据,所以需要同步
queueNumber.add(lastNumber);
return lastNumber++;
}
public synchronized Integer fetchServiceNumber(){//窗口取号
if(queueNumber.size() > 0){//在实际操作中,发现执行到此处附近时会出现数组角标越界异常,因此需要先判断queueNumber集合不为空元素时,再执行remove(0)的操作。
return queueNumber.remove(0);
}
}
}
取号机类NumberMachine
public class NumberMachine{
private NumberManager commonManager = new NumberManager();//普通号码管理器
private NumberManager expressManager = new NumberManager();//快速号码管理器
private NumberManager vipManager = new NumberManager();//VIP号码管理器
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();
}
服务窗口类ServiceWindow
public class ServiceWindow{
private CustomerType type = CustomerType.COMMON;//用枚举定义三种窗口类型
private int windowId = 1;//当前窗口号
public void start(){
Executors.newSingelThreadExecutor().execute(new Runnable(){
public void run(){
while(true){
swich(type){
case COMMON:
commonService();
break;
case EXPRESS:
expressService();
break;
case VIP:
vipService();
break;
}
if(type == CustomerType.COMMON){
NumberMachine.getInstance().getCommonManager();
}
}
});
}
}
//对窗口类型和窗口号提供set方法,用来切换窗口
public void setType(CustomerType type){
this.type = type;
}
public void setWindowId(int windowId){
this.windowId = windowId;
}
//普通窗口取号方法
private void commonService(){
String windowName = "第" + windowId + "号" + "普通" + "窗口"
Integer number = NumberMachine.getInstance().getCommonManager().fetchServiceNumber();
System.out.println(windowName + "正在获取任务");
if(number != null){//取到号码
System.out.println(windowName + "正在为第" + number + "个" + "普通" + "客户服务);
long beginTime = System.currentTimeMillis();
long maxRand = Constants.MAX_SERVICE_TIME - Constants.MIN_SERVICE_TIME;
long serverTime = new Random().nextInt(maxRand) + 1 + Constants.MIN_SERVICE_TIME;//休息的时间1-10秒
try{
Thread.sleep(serverTime);
}catch(){
}
long costTime = System.currentTimeMillis() - beginTime;
System.out.println(windowName + "为第" + number + "个" + "普通" + "客户完成服务,耗时" + costTime/1000 + "秒");
}else{//没有取到号
System.out.println(windowName + "没有取到服务任务,休息1秒");
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);//快速窗口办理时间为1秒
}catch(){
}
long costTime = System.currentTimeMillis() - beginTime;
System.out.println(windowName + "为第" + number + "个" + type + "客户完成服务,耗时" + costTime/1000 + "秒");
}else{//没有取到号
System.out.println(windowName +"没有取到服务任务");
commonService();//没有取到VIP任务时,为普通客户服务。
}
}
//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();
try{
Thread.sleep(Constants.MIN_SERVICE_TIME);//VIP窗口办理时间为1秒
}catch(){
}
long costTime = System.currentTimeMillis() - beginTime;
System.out.println(windowName + "为第" + number + "个" + type + "客户完成服务,耗时" + costTime/1000 + "秒");
}else{//没有取到号
System.out.println(windowName + "没有取到服务任务");
commonService();//没有取到VIP任务时,为普通客户服务。
}
}
}
窗口枚举类CustomerType
public enum CustomerType{
COMMON,EXPRESS,VIP;
public String toString(){
swich(this){
case COMMON:
return "普通";;
case EXPRESS:
return "快速";
case VIP;
return name();
}
return null;
}
}
定义常量类Constants
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;//普通客户间隔时间
}
主方法运行测试类MainClass:
public class MainClass{
public static void main(String[] args){
ServiceWindow commonWindow = null;
//创建5个普通窗口、1个VIP窗口和1个快速窗口
for(int i=1;i<5;i++){
commonWindow = new ServiceWindow();
commonWindow.setWindowId(i);
commonWindow.start();
}
ServiceWindow vipWindow = new ServiceWindow();
vipWindow.setType(CustomerType.VIP);
vipWindow.start();
ServiceWindow expressWindow = new ServiceWindow();
vipWindow.setType(CustomerType.EXPRESS);
vipWindow.start();
//创建普通客户对象。
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){
public void run(){
Integer number = NumberMachine.getInstance().getExpressManager().generateNewManager();
System.out.println(number + "号普通客户等待服务!");
}
},
0,
1,
TimeUnit.SECONDS);
//创建快速客户对象。
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 * 2,
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);
}
}