今天总结下银行调度管理系统。系统的需求是分为三类用户,分别是:普通用户(Common)、快速用户(Express)、VIP用户(VIP)。与此同时,对应着有三类服务窗口,分别是普通窗口服务(commonService)、快速窗口服务(expressService)、VIP窗口服务(vipService).其中普通窗口只能服务普通用户;快速窗口首先要服务快速用户,在没有快速客户时候还可以给普通客户办理业务;VIP窗口首先要为VIP用户服务,在没有VIP用户的时候还可以给普通用户办理业务。每个类型客户比例为,普通用户:快速客户:VIP客户=6:3:1.为用户服务的时间要在最大值与最小值之间,普通用户和VIP用户的服务时间在最大值与最小值之间取随机值,而为快速用户服务的时间去最小值。
在此,我们用枚举来创建用户,枚举的成员分别是COMMON、EXPRESS、VIP。因为每个成员的toString方法返回的字符串不同,所以我们重写了toString方法:
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 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;
}
有了号码保存器,我们还需要一个号码管理类,这个类就如同我们现实生活中的取号机,此机器管理每种用户类型的集合,所有的用户都在此机器上取号。因为这个系统只需要有一个取号器,所以我们将这个类设置成单例模式,在这个类中,我们需要保存三种类型的号码保存器,为每种类型的客户都保存一个。
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();
}
接下来设计带有三种服务窗口方法的类,主要功能是普通窗口只服务普通用户,快速窗口在有快速用户时,首先服务快速用户,没有快速用户时,可服务普通用户,VIP窗口在有VIP用户时首先服务VIP用户对象,没有VIP用户则可以服务普通用户,VIP用户和普通用户服务时间根据最大值和最小值中去随机数来确定,而快速用户则使用为最小时间。此类需要保存所属类型的成员变量,因为三种类型的窗口服务方式不同,所以要根据这个变量来区分要做的动作。窗口在程序运行时是并行的,所以我们为每个窗口都请求一个线程来模拟服务过程。
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) {
windowId = windowId;
}
public void start(){
Executors.newSingleThreadScheduledExecutor().execute(new Runnable(){
public void run()
{
while(true)
{
switch(type)
{
case COMMON:
commonservice();
break;
case EXPRESS:
expressservice();
break;
case VIP:
vipservice();
break;
}
}
}
});
}
public 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;
long serveTime=new Random().nextInt(maxRand)+1+Constants.MIN_SERVICE_TIME;
try {
Thread.sleep(serveTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
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();
}
}
}
public void expressservice() {
String windowName="第"+windowId+"号"+type+"窗口";
Integer number=NumberMachine.getInstance().getExpressManager().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;
//long serveTime=new Random().nextInt(maxRand)+1+Constants.MIN_SERVICE_TIME;
try {
Thread.sleep(Constants.MIN_SERVICE_TIME);
} catch (InterruptedException e) {
e.printStackTrace();
}
long costTime=System.currentTimeMillis()-beginTime;
System.out.println(windowName+"为第"+number+"个快速客户完成服务,耗时"+costTime/1000+"秒");
}else{
System.out.println(windowName+"没有取到任务");
commonservice();
}
}
public void vipservice() {
String windowName="第"+windowId+"号"+type+"窗口";
Integer number=NumberMachine.getInstance().getVipManager().fetchServiceNumber();
System.out.println(windowName+"正在获取任务!");
if(number!=null)
{
System.out.println(windowName+"为第"+number+"个VIP客户服务");
long beginTime= System.currentTimeMillis();
int maxRand=Constants.Max_SERVICE_TIME-Constants.MIN_SERVICE_TIME;
long serveTime=new Random().nextInt(maxRand)+1+Constants.MIN_SERVICE_TIME;
try {
Thread.sleep(serveTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
long costTime=System.currentTimeMillis()-beginTime;
System.out.println(windowName+"为第"+number+"个VIP客户完成服务,耗时"+costTime/1000+"秒");
}else{
System.out.println(windowName+"没有取到任务");
commonservice();
}
}
}
最后,创建主函数,我们要创建所需要各个类型的服务窗口,以及模拟三种类型的客户来取号,在方法中,我们用到调度线程池,用到了定时器,这样就把程序串联了起来。
public static void main(String[] args) {
// TODO Auto-generated method stub
for(int i=1;i<5;i++)
{
ServiceWindow commonWindow=new ServiceWindow();
commonWindow.setWindowId(i);
commonWindow.start();
}
ServiceWindow expressWindow=new ServiceWindow();
expressWindow.setType(CustomerType.EXPRESS);
expressWindow.start();
ServiceWindow vipWindow=new ServiceWindow();
vipWindow.setType(CustomerType.VIP);
vipWindow.start();
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){
public void run()
{
Integer number=NumberMachine.getInstance().getCommonManager().generateNewManager();
System.out.println(number+"号普通客户等待服务");
}
},
0,
Constants.CONMON_CUSTOMER_INTERVAL_TIME,
TimeUnit.SECONDS
);
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){
public void run()
{
Integer number=NumberMachine.getInstance().getExpressManager().generateNewManager();
System.out.println(number+"号快速客户等待服务");
}
},
0,
Constants.CONMON_CUSTOMER_INTERVAL_TIME*6,
TimeUnit.SECONDS
);
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){
public void run()
{
Integer number=NumberMachine.getInstance().getVipManager().generateNewManager();
System.out.println(number+"号VIP客户等待服务");
}
},
0,
Constants.CONMON_CUSTOMER_INTERVAL_TIME*2,
TimeUnit.SECONDS
);
}
---------------------- android培训、 java培训、期待与您交流! ----------------------