ASP.Net+Android+IOS开发.Net培训期待与您交流!
有如下要求:
1:有三种对应类型的客户:VIP客户,普通客户,快速客户
2:异步随机生成各种类型的客户,生成各类型用户的概率比例为:VIP客户:普通客户:快速客户=1:6:3
3:客户办理业务时间有最大值和最小值,在该范围内随机设定每个VIP客户以及普通客户客户办理业务所需时间,快速客户办理业务所需时间为最小值
4:各类型在其对象窗口按顺序依次办理业务
5:当VIP窗口和快速业务窗口没有相应客户办理业务的时候,这两个窗口可以处理普通客户的业务,而一旦有对应的客户等待办理业务的时候,则有限处理对应客户的业务。
6:随机生成客户时间间隔以及业务办理时间的最大值和最小值,可以自行设置。
7:不要求实现GUI,只需实现系统逻辑实现。
还是要求具有相应的面向对象的设计经验,应分为哪几个类,哪几个对象?在我们的生活中,每次去银行时,号码机都回生成一张号码代表你这个人,所以要想当生成一个号码产生器,不断随机的产生号码,也就是不断来客户。而有三种类型的客户,所以就有三种类型的号码产生器,这三种号码产生器是同步的,各自管理各自的号码,这三种号码产生器是由一个号码机器统一管理的,这个号码机器在整个系统中只能有一份,所以设计为单例。
用一张图表示即可
下面开始写号码管理器
import java.util.ArrayList;
import java.util.List;
public class NumberManage {
private int lastNumber = 1;//定义上一个号码
private List<Integer> queueNumber = new ArrayList<Integer>();//面向接口编程
//两个不同的线程访问了相同的数据,就可能会出问题,所以要加上synchronized产生互斥性
public synchronized Integer generateNewManage(){//号码产生器
queueNumber.add(lastNumber);
return lastNumber++;
}
public synchronized Integer fetchServiceNumber(){
//号码取号器,如果第一个为空的话queueNumber返回一个null,所以返回类型需要是类
if(queueNumber.size() >0)
return queueNumber.remove(0);
return null;
}
}
下面开始写三个号码管理器
public class NumberMachine {
public NumberManage commonManager = new NumberManage();//产生三个号码产生器
public NumberManage expressManager = new NumberManage();
public NumberManage vipManager = new NumberManage();
public NumberManage getCommonManager() {
return commonManager;
}
public NumberManage getExpressManager() {
return expressManager;
}
public NumberManage getVipManager() {
return vipManager;
}
//单例代码
private NumberMachine(){}//私有化构造方法,产生单例
private static NumberMachine numberMachine = null;
public static NumberMachine getInstance(){
if(numberMachine == null){
synchronized (NumberMachine.class) {
if(numberMachine == null)
numberMachine = new NumberMachine();
}
}
return numberMachine;
}
}
下面是三个服务窗口
import java.util.Random;
import java.util.concurrent.Executors;
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) {
this.windowId = windowId;
}
public void start(){
//并发库
Executors.newSingleThreadScheduledExecutor().execute(new Runnable(){//jdk1.5线程新特性
@Override
public void run() {
while(true){
if(type == CustomerType.COMMON){
commonService();
}
else if(type == CustomerType.EXPRESS){
expressService();
}else if(type == CustomerType.VIP){
vipService();
}
}
}
});
}
private void commonService() {
String windowName = "第"+windowId+"号"+type+"窗口";//这里重写了type的toString方法
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) {
// TODO Auto-generated catch block
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();
}
}
}
private 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();
try {
Thread.sleep(Constants.MIN_SERVICE_TIME);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
long costTime = System.currentTimeMillis()-beginTime;
System.out.println(windowName+"为第"+number+"个"+"快速客户完成服务,耗时"+costTime/1000+"秒");
}else{
System.out.println(windowName+"没有领取到任务,先休息1秒");
commonService();
}
}
private 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) {
// TODO Auto-generated catch block
e.printStackTrace();
}
long costTime = System.currentTimeMillis()-beginTime;
System.out.println(windowName+"为第"+number+"个"+"VIP客户完成服务,耗时"+costTime/1000+"秒");
}else{
System.out.println(windowName+"没有领取到任务");
commonService();
}
}
}
下面是客户类型,定义成枚举类型
public enum CustomerType {
COMMON,EXPRESS,VIP;
public String toString(){
if(this == COMMON)
return "一般";
else if(this == EXPRESS)
return "快速";
else if(this == VIP)
return "VIP客户";
return null;
}
}
下面是常量
public class Constants {
public static final int MAX_SERVICE_TIME = 1000;
public static final int MIN_SERVICE_TIME = 10000;
public static final int COMMON_CUSTOMER_INTERVAL_TIME = 1;
}
这里主要解决了以下几个问题:
1,三个NumberMachine产生于NumberManage,三个NumberMachine产生号码,也就是产生客户。
2,三个普通客户,快速客户,VIP客户负责各自的服务。
3,测试类使用定时器以1:3:6的比例产生VIP客户:快速客户:普通客户。
本文介绍了一个银行排队系统的模拟实现,通过三个不同类型的客户(VIP、普通、快速)和服务窗口进行交互,采用多线程和面向对象的方法实现了业务办理流程。

被折叠的 条评论
为什么被折叠?



