银行业务调度系统
1. 模拟实现银行业务调度系统逻辑,具体需求如下:
银行内有6个业务窗口,1 - 4号窗口为普通窗口,5号窗口为快速窗口,6号窗口为VIP窗口。
有三种对应类型的客户:VIP客户,普通客户,快速客户(办理如交水电费、电话费之类业务的客户)。
异步随机生成各种类型的客户,生成各类型用户的概率比例为:
VIP客户:普通客户:快速客户 = 1 :6 :3。
客户办理业务所需时间有最大值和最小值,在该范围内随机设定每个VIP客户以及普通客户办理业务所需的时间,
快速客户办理业务所需时间为最小值(提示:办理业务的过程可通过线程Sleep的方式模拟)。
各类型客户在其对应窗口按顺序依次办理业务。
当VIP(6号)窗口和快速业务(5号)窗口没有客户等待办理业务的时候,这两个窗口可以处理普通客户的业务,
而一旦有对应的客户等待办理业务的时候,则优先处理对应客户的业务。
随机生成客户时间间隔以及业务办理时间最大值和最小值自定,可以设置。
不要求实现GUI,只考虑系统逻辑实现,可通过Log方式展现程序运行结果。
2. 思路分析
分析: 有三种对应类型的客户:VIP客户,普通客户,快速客户,异步随机生成各种类型的客户,各类型客户在其对应窗口按顺序依次办理业务。其实每一个客户办理业务顺序的依据是他所取到的号码。所以要想到定义一个号码产生器,因为有三种不同类型的客户,所以要定义一个类来进行着三种客户进行管理。让哪个用户进行办理业务实际上是窗口进行不断的叫号,窗口叫号实际上就是想号码管理器要号。
类的功能代码实现
出号机类
public class NumberManager {
private int number=0;
private List<Integer> storeNumber=new ArrayList<Integer>();
//产生票
public synchronized Integer produceNumber()
{
storeNumber.add(++number);
//System.out.println(number+"");
return number;
}
//取票
public synchronized IntegerfetchNumber()
{
if(storeNumber.size()>0)
{
return (Integer)storeNumber.remove(0);
}
else
{
return null;
}
}
}
管理三种不同的号
public class NumberMechine {
private NumberManager commonNumber=new NumberManager();
private NumberManager rapidNumber=new NumberManager();
private NumberManager vipNumber=new NumberManager();
//获取普通用户
public NumberManager getCommonNumber() {
return commonNumber;
}
//获得快速用户
public NumberManager getRapidNumber() {
return rapidNumber;
}
//获得VIP用户
public NumberManager getVipNumber() {
return vipNumber;
}
private NumberMechine(){};
private static NumberMechine numbermechine=new NumberMechine();
public static NumberMechine getInstance()
{
return numbermechine;
}
}
窗口类:
import java.util.Random;
import java.util.concurrent.Executors;
public class Servicewindow {
private ComstorStyle type=ComstorStyle.COMMON;
private int number=1;
public ComstorStylegetType() {
return type;
}
public void setType(ComstorStyle type) {
this.type = type;
}
public void setNumber(int number) {
this.number = number;
}
public void start()
{
Executors.newSingleThreadExecutor().execute(new Runnable(){
@Override
public void run() {
while(true)
{
switch(type)
{
case COMMON:
commonService();
break;
case RAPID:
rapidService();
break;
case VIP:
vipService();
break;
}
}
}
});
}
//快速窗口的服务
private void rapidService() {
//System.out.println(Comstornumber+"======");
String windownumber="第"+number+"号"+type+"窗口";
System.out.println(windownumber+"正在获取快速用户!");
Integer Comstornumber=NumberMechine.getInstance().getCommonNumber().fetchNumber();
if(Comstornumber!=null)
{
System.out.println(windownumber+"正在准备为第"+Comstornumber+"号快速用户服务!");
// longstartTime=System.currentTimeMillis();
//int time= (int)((TimeConstant.TIME_MAX-TimeConstant.TIME_MIN)/1000);
// longworkTime=new Random().nextInt(time)+1+TimeConstant.TIME_MIN/1000;
try {
Thread.sleep(TimeConstant.TIME_MIN);
} catch (InterruptedException e) {
e.printStackTrace();
}
// longendTime=System.currentTimeMillis();
System.out.println(windownumber+"为第"+Comstornumber+"号普快速户服务完毕!");
}
else
{
System.out.println("快速窗口没有获取到快速用户,正等待为普通用户服务");
commonService();
System.out.println("快速窗口为普通用户服务!!");
}
}
//VIP窗口服务
private void vipService() {
String windownumber="第"+number+"号"+type+"窗口";
System.out.println(windownumber+"正在获取VIP用户!");
Integer Comstornumber=NumberMechine.getInstance().getCommonNumber().fetchNumber();
// System.out.println(Comstornumber+"----------");
if(Comstornumber!=null)
{
System.out.println(windownumber+"正在准备为第"+Comstornumber+"号VIP用户服务!");
// longstartTime=System.currentTimeMillis();
int time= (int) ((TimeConstant.TIME_MAX-TimeConstant.TIME_MIN));
long workTime=newRandom().nextInt(time)+1+TimeConstant.TIME_MIN;
try {
Thread.sleep(workTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
// longendTime=System.currentTimeMillis()/1000;
System.out.println(windownumber+"为第"+Comstornumber+"号VIP用户服务完毕!");
}
else
{
System.out.println("VIP窗口没有获取到VIP用户,正等待为普通用户服务");
commonService();
System.out.println("VIP窗口为普通用户服务!!");
}
}
//普通窗口服务
private void commonService() {
String windownumber="第"+number+"号"+type+"窗口";
System.out.println(windownumber+"正在获取普通用户!");
Integer Comstornumber=NumberMechine.getInstance().getCommonNumber().fetchNumber();
if(Comstornumber!=null)
{
System.out.println(windownumber+"正在准备为第"+Comstornumber+"号普通用户服务!");
int time= (int) ((TimeConstant.TIME_MAX-TimeConstant.TIME_MIN));
long workTime=newRandom().nextInt(time)+1+TimeConstant.TIME_MIN;
try {
Thread.sleep(workTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(windownumber+"为第"+Comstornumber+"号普通用户服务完毕!共用"+workTime/1000+"秒");
}
else
{
System.out.println("没有任务休息一秒!");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
用枚举定义了一个不同类型的用户:
public enum ComstorStyle {
COMMON,RAPID,VIP;
public String toString()
{
String name=null;
switch(this)
{
case COMMON:
name ="普通";
break;
case RAPID:
name="快速";
break;
case VIP:
name=name();
break;
}
return name;
}
}
专门用于定义常量的类:
public class TimeConstant {
public static final long TIME_MAX=10000;
public static final long TIME_MIN=1000;
public static final long TIME=1;
}
测试类:
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class BankTest {
public static void main(String[] args) {
//产生四个普通窗口
for(int i=1;i<5;i++)
{
Servicewindow commonwindow=new Servicewindow();
commonwindow.setNumber(i);
commonwindow.start();
}
//产生一个快速窗口
Servicewindow rapidwindow=new Servicewindow();
rapidwindow.setType(ComstorStyle.RAPID);
rapidwindow.start();
//产生一个VIP窗口
Servicewindow vipwindow=new Servicewindow();
vipwindow.setType(ComstorStyle.VIP);
vipwindow.start();
//模拟普通用户取票
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){
@Override
public void run() {
// TODO Auto-generatedmethod stub
Integer number=NumberMechine.getInstance().getCommonNumber().produceNumber();
//System.out.println(number+"8888888888888888888888888888");
System.out.println("第"+number+"普通用户已拿到号,正等待服务!!");
}
},
0,
TimeConstant.TIME,
TimeUnit.SECONDS);
//模拟VIP用户取票
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){
@Override
public void run() {
// TODO Auto-generatedmethod stub
Integer number=NumberMechine.getInstance().getVipNumber().produceNumber();
System.out.println("第"+number+"VIP用户已拿到号,正等待服务!!");
}
},
0,
TimeConstant.TIME*6,
TimeUnit.SECONDS);
//模拟快速窗口取票
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){
@Override
public void run() {
// TODO Auto-generatedmethod stub
Integer number=NumberMechine.getInstance().getRapidNumber().produceNumber();
System.out.println("第"+number+"快速用户已拿到号,正等待服务!!");
}
},
0,
TimeConstant.TIME*3,
TimeUnit.SECONDS);
}
}
运行结果:
总结:通过银行调度系统,学会的分析事物,比如说有不同的用户,但是只有一个取号的机子,所以想到了单例模式来确保只有一个取号机,因为要有三个不同的用户,所以这个取号机要管理这三个不同的用户对象,因为用户是规定好的,所以想到了用枚举。对于窗口叫号,它得向管理号的机子要。这就学到了一个重要的思想,随拥有数据,把方法就定义在谁身上。所以要向出号机要。