您的位置:首页 > 职场人生

黑马程序员——java基础学习(银行业务调度系统)

2014-02-24 15:39 453 查看
----------------------
ASP.Net+Android+IOS开发</a>、.Net培训、期待与您交流! ----------------------

需求:

     银行内有6个业务窗口,1- 4号窗口为普通窗口,5号窗口为快速窗口,6号窗口为VIP窗口。
     有三种对应类型的客户:VIP客户,普通客户,快速客户(办理如交水电费、电话费之类业务的客户)。

     异步随机生成各种类型的客户,生成各类型用户的概率比例为:

          VIP客户 :普通客户 :快速客户 =  1 :6 :3。

     客户办理业务所需时间有最大值和最小值,在该范围内随机设定每个VIP客户以及普通客户办理业务所需的时间,快速客户办理业务所需时间为最小值(提示:办理业务的过程可通过线程Sleep的方式模拟)。

      各类型客户在其对应窗口按顺序依次办理业务。

      当VIP(6号)窗口和快速业务(5号)窗口没有客户等待办理业务的时候,这两个窗口可以处理普通客户的业务,而一旦有对应的客户等待办理业务的时候,则优先处理对应客户的业务。

      随机生成客户时间间隔以及业务办理时间最大值和最小值自定,可以设置。

     不要求实现GUI,只考虑系统逻辑实现,可通过Log方式展现程序运行结果。

分析:

     客户类型(ServerNumberQueue)将客户类型看成是要服务的号。固定为三种类型(VIP客户 、普通客户、快速客户),可通过枚举实现。里面用List存储当前等待服务的对象。

          因为因为三个窗口可能会同时操作普通客户,所以要注意数据的正确性。用同步代码块来保证。

     客户类型机器(ServerNumberMachine)用于自动三种类型的客户服务号。

     服务窗口(ServiceWindow)服务客户。有三种类型窗口。

各个类的实现:

     客户类型(ServerNumberQueue)

public enum ServerNumberQueue {
VIP, COMMON, FAST;
private List<String> numberQueue;//存储当前等待服务的客户号码队列
private int currentNumber;		//记录当前客户号

private ServerNumberQueue() {
this.numberQueue = new LinkedList<String>();
//建立客户对象时,让客户号从一个4000-4999的随机数开始
this.currentNumber = new Random().nextInt(1000) + 4000;
}

public synchronized void setCurrentNumber(int num) {
if (this.numberQueue.size() == 0) {
this.currentNumber = num;
}
}
/*
* 当服务窗口为一个对象服务完毕,调用该方法将服务号从队列中移除
*   可能多个服务窗口会同时服务,要加同步代码块
*/
public synchronized String fetchNumber() {
if (this.numberQueue.size() > 0) {
return this.numberQueue.remove(0);
}
return null;
}
/*
* 当客户管理器产生了一个客户时,将其添加到队列中
*/
public synchronized String generateNumber() {
this.numberQueue.add(this.name() + " customer " + currentNumber++);
//System.err.println(this.numberQueue);
return this.numberQueue.get((this.numberQueue.size() - 1));
}

public synchronized int getQueueCount() {
return this.numberQueue.size();
}
}


     客户类型机器(ServerNumberMachine)
public class ServerNumberMachine {
//程序运行时,只有一个客户型管理的机器,单例。
private static ServerNumberMachine instance;
/*
* 单例实现:构造方法私有,通过一个静态方法返回对象。
*/
private ServerNumberMachine(){}
public static ServerNumberMachine getInstance(){
if(instance == null){
synchronized(ServerNumberMachine.class){
if(instance == null){
instance = new ServerNumberMachine();
}
}
}
return instance;
}
/*
* 当服务窗口为客户服务时,客户管理机器要把该客户从等待服务的客户队列中移除。
*/
public String fetchCustomer(String name){
return ServerNumberQueue.valueOf(name).fetchNumber();
}
/*
* 添加客户到队列中
*/
public void generateCustomer(String name){
String mes;
mes = ServerNumberQueue.valueOf(name).generateNumber();
System.err.println("'" + mes + "'来了.");
}
}


     服务窗口(ServiceWindow)

public class ServiceWindow {
private String windowName;//服务窗口名
private String windowType;//服务窗口类型
private int windowNumber;//窗口号
private ServerNumberMachine snm;
private ExecutorService pool;

public ServiceWindow(int number) {
this(ConstantsUnit.COMMON_CUSTOMER, number);
}

public ServiceWindow(String type, int number) {
this.windowType = type;
this.windowName = type;
this.windowNumber = number;
this.snm = ServerNumberMachine.getInstance();
this.pool = ThreadPool.getInstance().getExecutorService();
}

public void setWindowName(String windowName) {
this.windowName = windowName;
}

public void setWindowNumber(int windowNumber) {
this.windowNumber = windowNumber;
}

public int getWindowNumber() {
return this.windowNumber;
}

private boolean service() {
return service(windowType);
}
/*
* 查找客户并为客户服务功能
*/
private boolean service(String type) {
/*try {
Thread.sleep(2000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}*/
Random time = new Random();
//当前服务窗口sleep时间,以模拟为客户服务耗时。当为快速客户服务时,时间为1;否则随机产生一个时间
int servicetime = type.equals(ConstantsUnit.FAST_CUSTOMER) ?
ConstantsUnit.MIN_SERVICE_TIME
: time.nextInt(ConstantsUnit.MAX_SERVICE_TIME
- ConstantsUnit.MIN_SERVICE_TIME)
+ ConstantsUnit.MIN_SERVICE_TIME + 1;
String servicemess;
servicemess = snm.fetchCustomer(type);
if (servicemess != null) {
try {
/*				System.out.println(windowName + windowNumber + "正在为'"
+ servicemess + "'服务");*/
long stime = System.currentTimeMillis();
Thread.sleep(servicetime);
long etime = System.currentTimeMillis();
System.out.println(windowName + windowNumber + "为'"
+ servicemess + "'服务完毕,耗时:" + (etime - stime) / 1000
+ "秒.");
return true;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/*		if(type.equals(ConstantsUnit.COMMON_CUSTOMER)){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}*/
return false;
}
/*
* 调用此方法让窗口开始服务
*   VIP,快速窗口没有相应的客户时,要服务普通客户
*/
public void startService() {
pool.execute(new Runnable() {
@Override
public void run() {
while (true) {
switch (windowType) {
/*
* VIP窗口成功为VIP客户服务则要继续判断是否有VIP客户等待服务,否则判断是否有等待服务的
*   普通客户,有则要为普通客户服务
*/
case "VIP":
if(service())//将查找客户并服务单独封装成一个方法,调用service方法
break;
service(ConstantsUnit.COMMON_CUSTOMER);
break;
/*
* 快速窗口成功为快速客户服务则要继续判断是否有VIP客户等待服务,否则判断是否有等待服务的
*   普通客户,有则要为普通客户服务
*/
case "FAST":
if(service())
break;
service(ConstantsUnit.COMMON_CUSTOMER);
break;
case "COMMON":
service();
}
}
}
});
}

}


     用到的一些常(ConstantsUnit)

public class ConstantsUnit {
public static int MAX_SERVICE_TIME = 10000;//最大服务时间,毫秒
public static int MIN_SERVICE_TIME = 1000;//最小服务时间
public static String VIP_CUSTOMER = "VIP";
public static String COMMON_CUSTOMER = "COMMON";
public static String FAST_CUSTOMER = "FAST";
public static int GENERATE_CUSTOMER = 1;//产生普通客户的时间间隔

}


     测试功能否完成(Test)

public class Test {
public static void main(String[] args){

final ServerNumberMachine snm = ServerNumberMachine.getInstance();

ThreadPool pool = ThreadPool.getInstance();

for(int i=1; i<=4; i++){
//			System.out.println("创建普通服务窗口...");
new ServiceWindow(i).startService();
}
//		System.out.println("创建快速服务窗口...");
new ServiceWindow(ConstantsUnit.FAST_CUSTOMER, 5).startService();
//		System.out.println("创建VIP服务窗口...");
new ServiceWindow(ConstantsUnit.VIP_CUSTOMER, 6).startService();

//产生普通客户
pool.getScheduledExecutorService().scheduleAtFixedRate(
new Runnable(){
@Override
public void run() {
snm.generateCustomer(ConstantsUnit.COMMON_CUSTOMER);
}
},
0,
ConstantsUnit.GENERATE_CUSTOMER,
TimeUnit.SECONDS);
//产生VIP客户
pool.getScheduledExecutorService().scheduleAtFixedRate(
new Runnable(){
@Override
public void run() {
snm.generateCustomer(ConstantsUnit.VIP_CUSTOMER);
}
},
0,
ConstantsUnit.GENERATE_CUSTOMER*6,
TimeUnit.SECONDS);
//产生快速客户
pool.getScheduledExecutorService().scheduleAtFixedRate(
new Runnable(){
@Override
public void run() {
snm.generateCustomer(ConstantsUnit.FAST_CUSTOMER);
}
},
0,
ConstantsUnit.GENERATE_CUSTOMER*2,
TimeUnit.SECONDS);
}

}

----------------------
ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: