---------------------- android培训、java培训、期待与您交流! ----------------------
黑马程序员-银行业务调度系统
银行业务调度系统
模拟实现银行业务调度系统逻辑,需求:
1.银行内有6个业务窗口,1-4号窗口为普通窗口,5号为快速窗口,6号为vip窗口。、
有三种对应类型的客户:vip,普通,快速客户(交水电费电话费)
异步随机生成各种类型的客户,生成各种类型用户
比例为vip 普通 快速 =1:6:3
客户办理业务所需时间有最大值和最小值。在该范围内随机设定每个vip客户以及普通客户办理业务所需时间,快速客户业务办理时间为最小值
各类型客户在其对应的窗口按顺序一次办理业务。
当vip窗口和快速窗口没有客户办理时,可以处理普通客户的业务,一旦有客户等待办理的时候,有限办理对应的业务
随机生成时间间隔,以及业务办理时间最大最小值自定,可以设置
不实现GUI只考虑系统逻辑
面向对象的分析和设计
有三种对应类型的客户vip ,普通,快速。异步随机生成各种类型的客户,各客户类型在其对应窗口按顺序一次办理业务
因为每个客户其实就是有银行的号码机器产生的号码,所以先要有号码管理器
有三类客户,要有三个号码管理器对象,但是银行中的号码机器只有一个,所以,号码机器要设置为单例
各个类型的客户在其对应的窗口按顺序一次办理业务,窗口一次叫号。
服务窗口将找到号码管理器,获取当前要服务的号码
NumberManager类和NumberMachine类
NumberManager类
定义一个用于存储上一个客户号码的成员变量和用于存储所有等待服务的客户号码的队列集合
定义一个产生新号码的方法和获取马上要为之服务的号码的方法这两个方法被不同的线程操作了相同的数据,要进行同步
定义一个类用作号码发生器,即银行的取号机
import java.util.*;
//号码发生器
public class NumberManager {
//定义一个集合存储排队的号码,变量类型,尽量用父级或接口上一级,使其改变为List其他类型也可以,更灵活
private List<Integer> queueNumber=new ArrayList<Integer>();
//上一次返回的号码
private int lastNumber=1;
//客户来了获取号码
public synchronized Integer qenerateNewManager(){
//将产生的号码存入到集合中
queueNumber.add(lastNumber);
return lastNumber++;
}
//获取下一个要服务的号码
public synchronized Integer fetchServiceNumber(){
//取出号码,返回值就是被取走的号码
return queueNumber.remove(0);
}
}
定义一个类,用来获取服务号码,因为多个窗口操作同一个取号机对象,所以用单例模式
public class NumberMachine {
//创建三个私有对象,表示普通,快速,vip
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();
}
编写一个服务窗口的类,描述各个类型的窗口的服务过程
import java.util.Random;
import java.util.concurrent.Executors;
//服务窗口
public class ServiceWindow {
private CustomerType type=CustomerType.COMMON;
public void setType(CustomerType type) {
this.type = type;
}
public void setWindow(int window) {
this.windowid = window;
}
private int windowid=1;
//在开始内部启动一个线程
public void start(){
System.out.println(9999);
//使用jdk1.5的特性。这个是线程池的概念,去线程池内部找一个空闲线程执行。
//内部参数传入一个Runnable接口,匿名内部类的形式,
Executors.newSingleThreadExecutor().execute(new Runnable(){
public void run(){
while(true){
//可以用if进行判断,但是没有switch效率高。
switch(type){
case COMMON:
commonService();
break;
case EXPRESS:
expressService() ;
break;
case VIP:
vipService();
break;
}
}
}
});
}
private void commonService() {
//说出第几号窗口获取,用Type输出类型,要在枚举中创建toString方法。
String windowname="第"+windowid+"号"+type+"窗口";
System.out.println(windowname+"正在获取任务");
Integer number=NumberMachine.getInstance().getCommonManager().fetchServiceNumber();
if(number !=null){
//服务开始的时间
long beginTime=System.currentTimeMillis();
int maxRand=Constants.MAX_SERVICE_TIME-Constants.MIN_SERVICE_TIME;
//对客户服务的时间,产生1000--10000的随机数。
long serveTime=new Random().nextInt(maxRand)+1+Constants.MIN_SERVICE_TIME;
try {//等待客户服务时间
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
long costTime=System.currentTimeMillis()-beginTime;
System.out.println(windowname+"为第"+number+"个"+type+"客户服务完,耗时"+costTime/1000+"秒");
}else{
//没有取到任务,等待一秒,继续区号
System.out.println("没有取到服务任务,等待1秒时间");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void expressService() {
String windowname="第"+windowid+"号"+type+"窗口";
System.out.println(windowname+"正在获取任务");
Integer number=NumberMachine.getInstance().getExpressManager().fetchServiceNumber();
if(number !=null){
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+"个"+type+"客户服务完,耗时"+costTime/1000+"秒");
}else{
System.out.println(windowname+"没有获取到服务任务");
commonService();
}
}
private void vipService() {
String windowname="第"+windowid+"号"+type+"窗口";
System.out.println(windowname+"正在获取任务");
Integer number=NumberMachine.getInstance().getVipManager().fetchServiceNumber();
if(number !=null){
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+"个"+type+"客户服务完,耗时"+costTime/1000+"秒");
}else{
System.out.println(windowname+"没有获取到服务任务");
commonService();
}
}
}
定义一个类用于存放程序中用到的常量
//常量专门定义一个类,单独存放。
public class Constants {
public static int MAX_SERVICE_TIME=1000;
public static int MIN_SERVICE_TIME=10000;
public static int COMMON_CUSTOMER_INTERVAL_TIME=1;
}
因为窗口只有三种形式,所以使用枚举进行定义各个窗口类型
//用枚举的方式表示三个窗口
public enum CustomerType {
COMMON,EXPRESS,VIP;
//对外提供toString方法
public String toString(){
switch(this){
case COMMON:
return "普通";
case EXPRESS:
return "快速";
case VIP:
return name();
}
return null;
}
}
创建主类,创建各个窗口对象,并进行定时获取任务同时进行处理
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class MainClass {
public static void main(String[] args) {
System.out.println(13221);
//创建5个普通窗口
for(int i=1;i<5;i++){
ServiceWindow commonWindow =new ServiceWindow();
commonWindow.setWindow(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().qenerateNewManager();
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().qenerateNewManager();
System.out.println(number+"号快速客户等待服务");
}
},
0,
Constants.COMMON_CUSTOMER_INTERVAL_TIME*2,
TimeUnit.SECONDS);
//建立一个定时器。对vip客户服务进行定时
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){
public void run(){
//获取需要进行服务的vip客户号码
Integer number=NumberMachine.getInstance().getVipManager().qenerateNewManager();
System.out.println(number+"号vip客户等待服务");
}
},
0,
Constants.COMMON_CUSTOMER_INTERVAL_TIME*6,
TimeUnit.SECONDS);
}
}
---------------------- android培训、java培训、期待与您交流! ----------------------