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

黑马程序员_张孝祥7k面试题_银行调度系统

2013-03-26 10:07 756 查看
------- android培训java培训、期待与您交流! ----------
系统需求分析:

每个客户都需要一个号码排队,无论是快速客户还是vip客户,所以就得有一个号码管理类。

    号码管理类,得有个生成号码的方法,还有一个是排队的号码,并且这两个号码都是由生成号码方法产生的,排队的号码就可以放在一个集合里。所以生成号码的方法里面的号码放在集合里,而排队号码就是得到这个集合的第一个号码。

因为要有三个不同的号码管理类,所以号码器类须有三个号码管理类的对象。

   号码器类,在每个银行就一个号码生成器,所以要把它设计成单例模式,这样就只能产生一个对象,并且为了可以让别的类操作该类私有的三个不同的号码生成器的对象,需要为每个私有对象设置一个Getter方法。每个号码管理类都有自己的得到号码,和的得到排队号码的方法

   顾客类,因为顾客类只有三种,普通,快速,vip,所以可以把它设计成枚举类型,为了让提示信息显示中文,复写了toString()方法。

   窗口类,他有窗口名和类型的属性,窗口类型有,普通窗口,快速窗口,vip窗口,为了能让窗口通过窗口类型来服务顾客,就得有设置窗口类型的方法。以及设置窗口号码的方法。

这样,就可以通过不同窗口类型接待不同的顾客。

如:普通窗口通过实例化号码生成器中的普通的号码管理对象的等待号码的方法。

 代码实现:
号码管理类:
package cn.bank;
import java.util.*;
public class NumberManager {
//定义一个变量计数器,表示客户的号码
private Integer count = 1;
//定义一个集合,表示窗口服务的号码。
private List<Integer> turnNumList = new ArrayList<Integer>();
//客户取号方法	public synchronized int getNum(){
turnNumList.add(count);
return count++;
}
//窗口轮流的号
public synchronized Integer turnNum(){
if(turnNumList.size()>0)
return  turnNumList.remove(0);
else return null;
}


号码器:
package cn.bank;
//产生号码的机器
public class NumMchine {
//定义三个不同的号码管理
private NumberManager commanPer = new NumberManager();
private NumberManager quickPer = new NumberManager();
private NumberManager VIPPer = new NumberManager();
//号码产生机就一个,所以用单例模式实现构造。
private NumMchine(){};
private static NumMchine instance = new NumMchine();
public static NumMchine getInstance(){
return instance;
}
//得到不同的号码管理
public NumberManager getCommanPer() {
return commanPer;
}
public NumberManager getQuickPer() {
return quickPer;
}
public NumberManager getVIPPer() {
return VIPPer;
}
}

用户类:
package cn.bank;
public enum Customer {
commanPer,quickPer,VIPPer;
@Override
public String toString(){
switch (this)
{
case commanPer:
return "普通客户";
case quickPer:
return "快速客户";
case VIPPer:
return "VIP客户";
}
return  null;
}
}

窗口类:
package cn.bank;
import java.util.Random;
import java.util.concurrent.Executors;
public class Windows {
//窗口服务的顾客类型
private Customer type = Customer.commanPer;
//窗口的号码
private int number = 1;
//窗口的属性的Seter,Getter方法
public Customer getType() {
return type;
}
public void setType(Customer type) {
this.type = type;
}
public void setNumber(int number){
this.number = number;
}
//窗口服务的方法
public void start(){
// 创建一个使用单个 worker 线程的 Executor,以无界队列方式来运行该线程。
Executors.newSingleThreadExecutor().execute(
new Runnable(){
public void run(){
while(true){
switch(type){
//调用的普通用户窗口的方法
case commanPer:
commonService();
break;
case quickPer:
//调用的快速用户窗口的方法
expressService();
break;
case VIPPer:
//调用的vip用户窗口的方法
vipService();
break;
}
}
}
}
);
}
//普通用户窗口
private void commonService(){
//定义一个 窗口名字符
String windowName = "第" + number + "号" + type + "窗口";
//打印出窗口名字符
System.out.println(windowName + "开始获取普通任务!");
//得到轮到该普通窗口的号码
Integer serviceNumber = NumMchine.getInstance().getCommanPer().turnNum();
//如果有号码
if(serviceNumber != null ){
//输出客气语句
System.out.println(windowName + "开始为第" + serviceNumber + "号普通客户服务");
//计算机给定类常量的的值
int maxRandom = Constants.MAX_SERVICE_TIME - Constants.MIN_SERVICE_TIME;
//利用上述的值得到一个随机的数,此数用来模仿服务时间
int serviceTime = new Random().nextInt(maxRandom)+1 + Constants.MIN_SERVICE_TIME;
try {
//线程休息上述得到的随机数的时间
Thread.sleep(serviceTime);
}
catch (InterruptedException e) {
e.printStackTrace();
}
//打印睡了多久
System.out.println(windowName + "完成为第" + serviceNumber + "号普通客户服务,总共耗时" + serviceTime/1000 + "秒");
//如果没有号码
}
else{
//打印提示信息
System.out.println(windowName + "没有取到普通任务,正在空闲一秒");
try {
//休息1秒
Thread.sleep(1000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//快速用户的窗口
private void expressService(){
//得到标定为快速的号码
Integer serviceNumber = NumMchine.getInstance().getQuickPer().turnNum();
//定义一个 窗口名字符
String windowName = "第" + number + "号" + type + "窗口";
//打印提示信息
System.out.println(windowName + "开始获取快速任务!");
//如果有号码
if(serviceNumber !=null){
//打印提示信息
System.out.println(windowName + "开始为第" + serviceNumber + "号快速客户服务");
//定义一个服务的时间的数值
int serviceTime = Constants.MIN_SERVICE_TIME;
try {
//休息上述时间
Thread.sleep(serviceTime);
}
catch (InterruptedException e) {
e.printStackTrace();
}
//打印上述休息的时间,其实是服务的时间
System.out.println(windowName + "完成为第" + serviceNumber + "号快速客户服务,总共耗时" + serviceTime/1000 + "秒");
//没有号码
}
else{		//打印提示信息
System.out.println(windowName + "没有取到快速任务!");
//提供普通窗口服务
commonService();
}
}
//vip用户的窗口	private void vipService(){
//得到vip号码
Integer serviceNumber = NumMchine.getInstance().getVIPPer().turnNum();
//得到标定为快速的号码
String windowName = "第" + number + "号" + type + "窗口";
//打印提示信息
System.out.println(windowName + "开始获取VIP任务!");
//如果有vip号
if(serviceNumber !=null){
//打印提示信息
System.out.println(windowName + "开始为第" + serviceNumber + "号VIP客户服务");
int maxRandom = Constants.MAX_SERVICE_TIME - Constants.MIN_SERVICE_TIME;
//模仿服务时间
int serviceTime = new Random().nextInt(maxRandom)+1 + Constants.MIN_SERVICE_TIME;
try {
//服务时间
Thread.sleep(serviceTime);
}
catch (InterruptedException e) {
e.printStackTrace();
}
//打印提示信息
System.out.println(windowName + "完成为第" + serviceNumber + "号VIP客户服务,总共耗时" + serviceTime/1000 + "秒");
//没有vip号
}else{
//打印提示信息
System.out.println(windowName + "没有取到VIP任务!");
//转为普通窗口口服务
commonService();
}
}
}


自定义常量:
package cn.bank;
//自定义具有常量值的类
public class Constants {
public static int MAX_SERVICE_TIME = 10000; //10秒!
public static int MIN_SERVICE_TIME = 1000; //1秒!
public static int COMMON_CUSTOMER_INTERVAL_TIME = 1;
}

主类:
package cn.bank;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class BankTest {
public static void main(String[] args)
{
//创建4个普通窗口
for(int i=1;i<5;i++){
Windows commonWin = new Windows();
commonWin.setNumber(i);
commonWin.start();
}
//一个快速窗口
Windows quickWindow = new Windows();
quickWindow.setType(Customer.quickPer);
quickWindow.start();
//一个vip窗口
Windows VIPWindow = new Windows();
VIPWindow.setType(Customer.VIPPer);
VIPWindow.start();
//普通客户取号,创建一个单线程执行程序,它可安排在给定延迟后运行命令或者定期地执行。
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable(){
@Override
public void run() {
//取号
Integer serviceNumber = NumMchine.getInstance().getCommanPer().getNum();
System.out.println("第" + serviceNumber + "号普通客户正在等待服务!");
}
},
0,//首次执行任务延迟的时间
Constants.COMMON_CUSTOMER_INTERVAL_TIME, // 连续执行之间的周期
TimeUnit.SECONDS//时间单位,秒
);
//快速客户取号,创建一个单线程执行程序,它可安排在给定延迟后运行命令或者定期地执行。
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable(){
public void run(){
//取号
Integer serviceNumber = NumMchine.getInstance().getQuickPer().getNum();
System.out.println("第" + serviceNumber + "号快速客户正在等待服务!");
}
},
0,//首次执行任务延迟的时间
Constants.COMMON_CUSTOMER_INTERVAL_TIME * 2 ,// 连续执行之间的周期
TimeUnit.SECONDS);//时间单位,秒
//VIP客户取号,创建一个单线程执行程序,它可安排在给定延迟后运行命令或者定期地执行。
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){
public void run(){
//取号
Integer serviceNumber = NumMchine.getInstance().getVIPPer().getNum();
System.out.println("第" + serviceNumber + "号VIP客户正在等待服务!");
}
},
0,//首次执行任务延迟的时间
Constants.COMMON_CUSTOMER_INTERVAL_TIME * 6,// 连续执行之间的周期
}
}


 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息