重新来看一下这个银行业务调度系统。 在张老师的解说下我们能较好的理解它。
1:分析
* 首先是有三种类型的服务窗口:普通窗口,快速窗口,VIP窗口。
* 每个人来到银行我们就为它生成一个号码。然后通过叫号的形式为它服务。
* 叫号因为三种类型的客户所产生的方式不一样, 所以每种客户都有自己的号码管理器。
* 但是每个号码管理器在实际当中其实都是集成在一个号码机器上面。号码机器只能有一个。三个号码管理器。
* 因为是号码管理器在管理着号码,等于就是说号码管理器都都装着人呢,所以每次窗口也就是银行的工作人员
每次都是通过号码管理器来叫号进行服务。
* 窗口一启动,也就是说工作人员一开始工作,窗口就不停地工作了,每个窗口都相当于一个单独的线程。
* 人员的到来也是通过线程来随机的产生。
2:首先设计一个号码管理器(其实就是对客户的增加与减少操作一样)
public class NumberManager {
private List<Integer> customers = new ArrayList<Integer>();
private int number = 1;
//因我多个窗口可能会同时来取号和增加客户,所以方法要用synchronized上锁
public synchronized Integer getGeneratorNumber() {
customers.add(number);//每来一个客户装进去一个
return number++; //同时返当前加入客户,number是唯一用来标识客户的不同,这里我们没有单独的设计客户
}
//取号
public synchronized Integer fetchNumber() {
Integer number = null;
if(customers.size()>0) {
number = customers.remove(0);
}
return number;
}
}
2:设计一个号码机器来管理着这三个号码管理器,似乎像一个小型的简单工厂一样来生产着这三种号码管理器。
package com.moom;
public class NumberMachine {
//生成三个号码管理器
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() {
}
private static NumberMachine machine;
//单例的形式,在用到的时候我才进行初始化,就如单例中的赖汉式一样吧
public static NumberMachine getInstance() {
if(machine == null) {
machine = new NumberMachine();
}
return machine;
}
}
3:设计窗口:窗口有类型和ID属性,窗口一创建就开始执行它自有的线程开始工作。工作的时候根据窗口的类型做相应的操作。(这里就是其实还应该能过继承的方式或者直接的方式来
体现更好,觉得窗口本来就已经知道自己的是做什么的,我为什么还要在我做的时候判断一个我的类型呢,这显然不是多余的操作不)。我这里还是利用原来的判断进行操作 ,这样
也能更好的理解。
每个VIP,EXPRESS窗口在它没有人在服务的时候,它们也可以为普通窗口进行服务。
package com.moom;
import java.util.Random;
import java.util.concurrent.Executors;
public class WindowService {
// 窗口类型(也同时就是说是客户的类型),因为只有三种类型,就用枚举来体现吧
private CustomerType type = CustomerType.COMMON;
// 对应窗口类型号窗口ID也就相当于说是给个标识一下来区别
private int windowId = 1;
// 通过set方法进行了设置,能较好的在后期改变其类型,而不是说通过构造方法让它以后不能改变它的类型了
public void setType(CustomerType type) {
this.type = type;
}
public void setWindowId(int windowId) {
this.windowId = windowId;
}
// 窗口一创建就开始服务,和实际生活想对应,每个窗口是一个单独的线程
public void start() {
// 通过JDK1.5的新特性来创建程
Executors.newSingleThreadExecutor().execute(new Runnable() {
@Override
public void run() {
// 是不停的取,所以暂时用一个死循环来做到这种要求
while (true) {
//根据窗口的为类型来做相应的服务
switch (type) {
case COMMON:
commonservice(); //调用普通窗口的实现方法来做事
break;
case EXPRESS:
expressservice(); //方法我这里就不写了,因普通方法大概一样,只是在没有取到的时候它会调用普通方法来做事
break;
case VIP:
vipservice();
break;
}
}
}
});
}
private void commonservice() {
String windowName = "第" + windowId + "个"+type+"窗口";
System.out.println(windowName + "正在获取任务");
Integer number = NumberMachine.getInstance().getCommonManager().fetchNumber();
// 如果number是空的话就没有取到任务,不为空就是取到了任务
if (number != null) {
System.out.println(windowName +"取到任务:" + "普通客户" + number);
long startTime = System.currentTimeMillis();
try {
Thread.sleep(new Random().nextInt(Constant.MAX_TIME-Constant.MIN_TIME) +1 + Constant.MIN_TIME);
} catch (InterruptedException e) {
e.printStackTrace();
}
long costTime =(System.currentTimeMillis()- startTime) /1000;
System.out.println(windowName + "为第" + number + "个普通客户完成服务,用时:" + costTime + "秒");
} else {
System.out.println(windowName + "没用取到任务,休息一秒钟吧");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
4:设计测试类
* 建立所有要用到的窗口
* 为每个窗口随机的生成客户
public static void main(String[] args) {
for(int i=1; i<5; i++) {
ServiceWindow commonWindow = new ServiceWindow();
commonWindow.setWindowId(i);
commonWindow.start();
}
ServiceWindow vipWindow = new ServiceWindow();
vipWindow.setType(CustomerType.VIP);
vipWindow.start();
ServiceWindow expressWindow = new ServiceWindow();
expressWindow.setType(CustomerType.EXPRESS);
expressWindow.start();
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
int number = NumberMachine.getInstance().getCommonManager().generateNewNumber();
System.out.println(number + "号普通用户等待服务");
}
},
0, 1, TimeUnit.SECONDS);
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
int number = NumberMachine.getInstance().getExpressManager().generateNewNumber();
System.out.println(number + "号快速用户等待服务");
}
},
0, 3, TimeUnit.SECONDS);
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
int number = NumberMachine.getInstance().getVipManager().generateNewNumber();
System.out.println(number + "号VIP用户等待服务");
}
},
0, 6, TimeUnit.SECONDS);
}
5:总结:面向对象的思维如果能很好的应用到实际工作当中将有利于我们快速的解决许多问题。
银行业务调度系统
最新推荐文章于 2024-08-13 20:32:39 发布