---------------------- android培训,java培训、期待与您交流! ----------------------
银行业务调度系统:
现实生活中,银行会提供3种服务: 普通客户服务, VIP客户服务 ,快速客户服务. 所以银行会提供3种服务窗口 : 普通服务窗口 , VIP服务窗口 , 快速服务窗口.
普通服务窗口只为普通客户服务 ;
VIP服务窗口为VIP客户服务,当没有VIP客户需要办理业务的时候, 也可以为普通客户服务;
快速服务窗口为需要办理快速业务(交水电费,电话费之类) 客户服务,当没有需要办理快速业务的客户需要办理业务的时候, 也可以为普通客户服务 .
面向对象分析:
办理银行业务的客户都要有一个号码, 这些号码都放在一个号码机器里面. 由于3中用户的号码都是相对独立的,普通客户取了1号 , VIP客户同样可以取到1号, 但是银行中的取号机可以取3种类型的号码, 所以取号机应该设计为单例的.
窗口通过叫号的方式来提醒客户来办理业务, 所以需要一个号码管理器来生成新的号码和告诉窗口轮到哪些号码的客户办理业务.
服务窗口分为3种窗口, 可以为号码管理器提供的客户服务.
思路分析:
号码机器:
号码机器中有3个属性,分别对应3种号码. 3种号码都是相互独立的,所以号码机器应该设置为单例的.
/*
* 号码机器
publicclass NumberMachine {
//单例: 构造方法私有化, 私有的创建一个静态的本类对象 , 通过一个公共的方法返回本类对象
private NumberMachine(){}
privatestatic NumberMachine instance =new NumberMachine();
public NumberMachine getInstance(){
returninstance;
}
//三种号码类型
private NumberManager commonManager = new NumberManager();
private NumberManager expressManager =new NumberManager();
private NumberManager VIPManager=new NumberManager();
public NumberManager getCommonManager() {
returncommonManager;
}
public NumberManager getExpressManager() {
returnexpressManager;
}
public NumberManager getVIPManager() {
returnVIPManager;
}
}
号码管理器:
号码管理器中应该有两个属性和两个方法.
属性是: int lastNumber 和 List集合 ;
lastNumber 用于记录号码, 号码是按照顺序往上加的, 每来一个客户, 就加1次;
List集合用于存放lastNumber, 把有号码的客户统计起来,然后逐个办理业务.
方法是: generatrNewNumber() 和 fetchNumber().
generatrNewNumber()产生号码, 把lastNumber存入List集合.
fetchNumber()提取排在最前面的号码来办理业务.
/*
* 号码管理器
* */
import java.util.*;
class NumberManager {
privateintlastNumber=1; //号码
private List<Integer> queueNumber= new ArrayList<Integer>();//集合,用于存放号码
//产生新的号码,并把号码存入集合
public synchronizedint generateNumber (){
queueNumber.add(lastNumber);
returnlastNumber++;
}
//提取最前面的号码去办理业务
public synchronizedint fetchNumber(){
if(queueNumber.size()>0)
returnqueueNumber.remove(0);
else
return 0;
}
}
服务窗口:
服务窗口中有一个开始服务的方法,这个方法里面封装了3个线程,分别是为普通客户, 快速客户和VIP客户服务的窗口.
每个窗口通过NumberMachine来获取要服务的号码, 普通窗口如果获取到了要服务的号码,就会随机产生服务用时,并且打印出来, 如果没有获取到号码,就休息1秒. 快速窗口和VIP窗口也要获取号码,如果没有获取到对应的号码, 就会去获取普通客户的号码 .
为了知道获取到哪种类型的客户, 就要用枚举来限定3种类型, 枚举中的对象分别是:
COMMON , EXPRESS, VIP
import java.util.Random;
import java.util.concurrent.Executors;
publicclass ServiceWindow {
private CustomerType type = CustomerType.COMMON;
privateintwindowId = 1; // 窗口号
publicvoid setType(CustomerType type) {
this.type = type;
}
publicvoid setWindowId(int windowId) {
this.windowId = windowId;
}
publicvoid start() {
Executors.newSingleThreadExecutor().execute(new Runnable() {
@Override
publicvoid run() {
// TODO Auto-generated method stub
// 通过号码机取号
while (true) {
switch (type) {
caseCOMMON:
commonService();
break;
caseEXPRESS:
expressService();
break;
caseVIP:
vipService();
break;
}
}
}
});
}
//普通服务窗口
privatevoid commonService() {
String windowName = "第" + windowId + "号" + type + "窗口"; // 窗口名
System.out.println(windowName + "正在开始获取普通服务!");
Integer serviceNumber = NumberMachine.getInstance() // 取号
.getCommonManager().fetchNumber();
if (serviceNumber != null) { // 如果取到号码
System.out.println(windowName + "正在为" + serviceNumber + "号" + type
+ "客户服务~!!");
int costTime = new Random().nextInt(9000) + 1000;
try {
Thread.sleep(costTime);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out
.println(windowName + "为普通客户服务,一共耗时 : ( " + costTime/1000 + " ) 秒!!");
} else {
System.out.println(windowName + "没有获取到普通服务,休息1秒!");
try {
Thread.sleep(1000);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
//快速服务窗口
privatevoid expressService(){
String windowName="第"+windowId+"号"+type+"窗口";
//取号
System.out.println(windowName + "正在开始获取普通服务!");
Integer serviceNumber=NumberMachine.getInstance().getExpressManager().fetchNumber();
if(serviceNumber!=null){
System.out.println(windowName+"正在为"+type+"客户服务");
try {
Thread.sleep(1000);
} catch (Exception e) {
// TODO: handle exception
}
System.out.println(windowName+"为"+type+"客户服务共用时 : ( 1 )秒!!");
}else{
System.out.println(windowName+"没有获取到"+type+"业务."); //当没有获取到快速服务的时候,就去获取普通服务
commonService();
}
}
//VIP 服务窗口
privatevoid vipService(){
String windowName="第"+windowId+"号"+type+"窗口";
System.out.println(windowName + "正在开始获取普通服务!");
Integer serviceName=NumberMachine.getInstance().getVIPManager().fetchNumber();
if(serviceName!=null){
System.out.println(windowName+"正在为"+type+"客户服务!");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(windowName+"为"+type+"客户服务共用时 : ( 1 ) 秒");
}else{
System.out.println(windowName+"没有获取到"+type+"业务.");
commonService();
}
}
}
主函数:
要在主函数中创建 4个普通窗口 , 1个快速窗口和1个VIP窗口,还要通过线程来按照一定时间创建客户.
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
publicclass MainClass {
publicstaticvoid main(String[] args) {
//不同客户出现的频率(时间单位为秒)
finalint com=1;
finalint express=3;
finalint vip=6;
//创建普通服务窗口
for (int i = 1; i < 5; i++) {
ServiceWindow common=new ServiceWindow();
common.setType(CustomerType.COMMON);
common.setWindowId(i);
common.start();
}
//创建快速服务窗口
ServiceWindow expressWin = new ServiceWindow();
expressWin.setType(CustomerType.EXPRESS);
expressWin.start();
//创建VIP服务窗口
ServiceWindow vipWin = new ServiceWindow();
vipWin.setType(CustomerType.VIP);
vipWin.start();
//创建普通客户
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){
@Override
publicvoid run() {
// TODO Auto-generated method stub
Integer serviceNumber=NumberMachine.getInstance().getCommonManager().generateNumber();
System.out.println("第"+serviceNumber+"普通客户等待服务!");
}
},
0,
com,
TimeUnit.SECONDS
);
//创建快速客户
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){
@Override
publicvoid run() {
// TODO Auto-generated method stub
Integer serviceNumber=NumberMachine.getInstance().getExpressManager().generateNumber();
System.out.println("第"+serviceNumber+"快速客户等待服务!");
}
},
0,
express,
TimeUnit.SECONDS
);
//创建VIP客户
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){
@Override
publicvoid run() {
// TODO Auto-generated method stub
Integer serviceNumber=NumberMachine.getInstance().getVIPManager().generateNumber();
System.out.println("第"+serviceNumber+"VIP客户等待服务!");
}
},
0,
vip,
TimeUnit.SECONDS
);
}
}
总结:
在学习银行调度系统的过程中又学到了一些新技术: 在jdk1.5 的 switch中除了可以使用 int 及其以下类型之外, 还可以使用枚举, 并且在case语句中可以省略前缀名. 线程池, 定时器.
---------------------- android培训,java培训、期待与您交流! ----------------------
详细请查看http://edu.youkuaiyun.com/heima