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

黑马程序员_银行业务调度系统

2014-05-08 11:27 323 查看
题目:银行业务调度

需求:

1) 银行窗口的分类

银行内有6个业务窗口:分三类窗口

(1) 1~4号窗口为普通窗口

(2) 5号窗口为快速窗口

(3) 6号窗口为VIP窗口。

2) 客户的种类和比例

(1) 客户的种类

<1> VIP客户

<2> 普通客户

<3> 快速客户 (办理如交水电费、电话费之类业务的客户)

(2) 客户的比例

<1> 异步随机生成各种类型的客户

<2> 生成各类型用户的概率比例为

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

3) 客户办理业务的时间规定

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

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

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

4) VIP窗口和快速业务窗口的额外要求

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

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

面向对象分析所需类

去过银行办业务的人都知道:第一步,取号(有几种不同的号,本题直接简化成三种普通,快速,VIP);第二步,等待叫号;第三步,叫号办理业务。一次循环

分析所需类:叫号机(NumbleMachine),三种不同号(号码管理器(NumbleManager)),服务窗口(ServiceWindow)。

对所需类进行设计

1.号码管理器(NumbleManager)

(1)号码管理器应该有两个方法产生号码generateNewNumber()和让服务窗口知道这个号码fetchServiceNumber()

(2)具体代码

package cn.itcast.bank;
import java.util.ArrayList;
import java.util.List;
public class NumberManager {
private int lastNumber =1;  //银行编号都从1开始
//肯定是产生多个客户这里的客户 简化用Integer类型来标示
private List<Integer> queueNumber =new ArrayList<Integer>();
//产生新号码的方法
public synchronized Integer generateNewNumber(){
queueNumber.add(lastNumber);
return lastNumber++;
}
//告诉服务台的方法
public synchronized Integer fetchServiceNumber(){
Integer number = null;
if(queueNumber.size() >0){
return queueNumber.remove(0);
}
return number;
}
}


2.叫号机(NumbleMachine)

(1)去过银行的人都知道,银行一般只有一个叫号机,因此叫号机必须是单例,可以把号码管理器作为其成员

(2)具体代码

package cn.itcast.bank;
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;
}
//获取VIP客户的号码管理器
public NumberManager getVipManager() {
return vipManager;
}
//叫号机的单例设计
private NumberMachine(){}
private static final NumberMachine instance =new NumberMachine();
public static NumberMachine getInstance(){
return instance;
}
}


3.服务窗口(ServiceWindow)

(1)注意快速窗口和VIP窗口,没业务时要做普通窗口的业务

(2)具体代码

package cn.itcast.bank;
import java.util.Random;
import java.util.concurrent.Executors;
public class ServiceWindow {
//窗口的性质
private CustomerType type = CustomerType.COMMON; //默认为普通类型的客户
//窗口的编号
private int windowId =1;
//窗口的type
public void setType(CustomerType type) {
this.type = type;
}
//窗口的号码
public void setWindowId(int windowId) {
this.windowId = windowId;
}
//窗口进行服务的代码
public void start(){
Executors.newSingleThreadExecutor().execute(new Runnable(){
public void run() {
//对各种类型的客户进行叫号
while(true){
//判断客户的类型 以便进行不同的操作
switch(type){
case COMMON:
commonService();
break;
case EXPRESS:
expressService();
break;
case VIP:
vipService();
break;
}
}
}

});
}
//普通窗口的服务代码
private void commonService() {
StringwindowName ="第"+ windowId +"号" +type+"窗口";
System.out.println(windowName+ "正在获取任务...");
//获取要服务的客户号码
Integer number =
NumberMachine.getInstance().getCommonManager().fetchServiceNumber();
if(number !=null){
System.out.println(windowName+"正在为第"+ number+"个普通客户服务...");
//普通客户要求服务的时间在一个范围内的随机值
int maxInterval =Constants.MAX_SERVICE_INTERVAL_TIME -Constants.MIN_SERVICE_INTERVAL_TIME;
int serviceTime =new Random().nextInt(maxInterval) +1+Constants.MIN_SERVICE_INTERVAL_TIME;
long beginTime =System.currentTimeMillis();
try {
//模拟服务
Thread.sleep(serviceTime);
}catch (InterruptedException e) {
e.printStackTrace();
}
long endTime =System.currentTimeMillis();
//服务完成啦
System.out.println(windowName +"为第"+number+"个普通客户完成服务。耗时: "+(endTime -beginTime)/1000+"s");
}else{
//没有获取到号码
System.out.println(windowName +"没有获取到号码,休息一秒钟。。");
try {
Thread.sleep(1000);
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//快速窗口为快速客户服务代码
private void expressService() {
StringwindowName ="第"+ windowId +"号 "+ type+"窗口";
System.out.println(windowName+ "正在获取任务...");
Integer number=
NumberMachine.getInstance().getExpressManager().fetchServiceNumber();

if(number !=null){
System.out.println(windowName+"正在为第"+ number+"个快速客户服务...");
int serviceTime = Constants.MIN_SERVICE_INTERVAL_TIME;
long beginTime =System.currentTimeMillis();
try {
Thread.sleep(serviceTime);
}catch (InterruptedException e) {
e.printStackTrace();
}
long endTime =System.currentTimeMillis();
//服务完成啦
System.out.println(windowName +"为第"+number+"个"+ type+"客户完成服务。耗时: "+(endTime -beginTime)/1000+"s");
}else{
//没有获取到号码则为普通用户进行服务
System.out.println(windowName+"此时没有获取到任何"+ type+ "号码");
commonService();
}

}
// VIP窗口为VIP客户服务代码
private void vipService() {
StringwindowName ="第"+ windowId +"号" +type+"窗口";
System.out.println(windowName+ "正在获取任务...");
//获取要服务的客户号码
Integer number =
NumberMachine.getInstance().getVipManager().fetchServiceNumber();
if(number !=null){
System.out.println(windowName+"正在为第"+ number+"个 VIP客户服务...");
int maxInterval =Constants.MAX_SERVICE_INTERVAL_TIME -Constants.MIN_SERVICE_INTERVAL_TIME;
int serviceTime =new Random().nextInt(maxInterval) +1+Constants.MIN_SERVICE_INTERVAL_TIME;
long beginTime =System.currentTimeMillis();
try {
//模拟服务
Thread.sleep(serviceTime);
}catch (InterruptedException e) {
e.printStackTrace();
}
long endTime =System.currentTimeMillis();
//服务完成啦
System.out.println(windowName +"为第"+number+"个普通客户完成服务。耗时: "+(endTime -beginTime)/1000+"s");
}else{
//没有获取到号码则为普通用户进行服务
System.out.println(windowName+"此时没有获取到任何"+ type+ "号码");
commonService();
}
}
}


4.主函数(MainClass)

(1)这个主函数的开启9个线程(6个窗口,3个生成号)

(2)具体代码

package cn.itcast.bank;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class MainClass {
public static void main(String[] args) {
//新建普通客户窗口并启动
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();
//新建VIP窗口并启动
ServiceWindow vipWindow =new ServiceWindow();
vipWindow.setType(CustomerType.VIP);
vipWindow.start();
//模拟普通客户的到来
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){
public void run() {
Integer number =
NumberMachine.getInstance().getCommonManager().generateNewNumber();
System.out.println(number+"号普通客户等待服务...");
}
},
0,
Constants.COMMON_CUSTOMER_INTERVAL_TIME,
TimeUnit.SECONDS);
//模拟快速客户的到来
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){
public void run() {
Integer number =
NumberMachine.getInstance().getExpressManager().generateNewNumber();
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().generateNewNumber();
System.out.println(number+"号VIP客户等待服务...");
}
},
0,
Constants.COMMON_CUSTOMER_INTERVAL_TIME*6,
TimeUnit.SECONDS);
}
}

5.辅助类

(1)常量类

public class Constants {
public static final int MAX_SERVICE_INTERVAL_TIME =10000; //最大服务间隔时间
public static final int MIN_SERVICE_INTERVAL_TIME =1000;  //最小服务间隔时间
public static final int COMMON_CUSTOMER_INTERVAL_TIME =1; //普通客户间隔时间
}


(2)枚举类

public enum CustomerType {
COMMON,EXPRESS,VIP;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: