学习银行业务调度系统一些理解
来源:互联网 发布:印度赶超中国 知乎 编辑:程序博客网 时间:2024/06/03 18:08
学习了银行业务调度系统,我认为除了面向对象的基础意外,要有一个比较重要的知识点就是Java5特性里面的一个线程池,线程的同步和枚举的使用。使用枚举可以很好的判断等候的客户是属于那一类客户、使用线程池和线程的同步可以很好的避免不管客户拿号还是窗口叫号的混乱。
NumberManager:该类我认为就相当于一个号码管理器一样,用来管理窗口的叫号和不同客户来取号。该类定义一个集合用来存储等待服务的客户号码和上一个客户号码的变量。一个方法是用来拿号一个方法是用来叫号,我们就应该想到,如果这两个方法被同一个线程调用或许出现的问题不大,但是如果被不同的线程调用,可能就会造成拿号跟叫号的混乱,所以,对这两个方法就要进行同步。
private int lastNumber = 0;
private List queueNumbers = new ArrayList();
public synchronized Integer generateNewNumber(){
queueNumbers.add(++lastNumber);
return lastNumber;
}
/*
* 客户来了,窗口要取号(客户)
* 这里返回值为什么不用int而用Integer?
* 因为用int,当取号为0的时候就为空,而用Integer会自动装箱和拆箱
* 当然这里面用集合的大小来判断,就更不会出现返回值为空的现象
*/
public synchronized Integer fetchNumber(){
if(queueNumbers.size()>0){
return (Integer)queueNumbers.remove(0);
}else{
return null;
}
}
NumberMachine:主要创建3不同客户(vip、普通、快速)的NumberManager对象的管理器,并实例化。使用get方法返回这3个客户的NumberManager对象。定义一个私有的构造函数,禁止其它类的使用。还要定义一个静态的方法,用来返回该类(NumberManager)的对象,这样可以避免获取客户对象的混乱。
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;
}
CustomerType:该类是一个枚举类,用来表示三种不同的客户:vip客户(COMMON)、普通客户(EXPRESS)、快速客户(VIP)这三个元素,并重写toString方法,返回元素的相对应的中文名称:比如是EXPRESS返回的中文名称就是“普通”。”
ServiceWindow:从类名上了解就是服务窗口,主要是用来处理一些逻辑上的信息。判读哪个窗口服务哪个一类客户,哪些窗口是空闲的。这里有一点要提的是,因为vip窗口不仅可以为vip客户服务,在没有vip客户空闲的时候,还可以为普通和快速客户服务。所以这一点大家要理解清楚。该类实现了一个start()方法,用来判断来的客户属于哪一种类型的客户。该放实现了一个单个的线程池,线程池里面实现了个run()方法,就是用来判断哪类客户的。
public void start(){
Executors.newSingleThreadExecutor().execute(
new Runnable(){
public void run(){
while(true){
switch(type){
case COMMON:
commonService();
break;
case EXPRESS:
expressService();
break;
case VIP:
vipService();
break;
}
}
}
}
);
}
在switch里面的case语句都调用的相应的方法。每个方法都基本上的实现了同一个功能,在细节上都稍微有些区别。我就拿普通窗口(commonService())的方法来说,该方法只要是通过NumberMachine的对象来得到号码管理器(NumberManager)窗口要取号的方法fetchNumber()。因为每个窗口服务的时间都有服务的最大值和最小值,通过计算这两个值之间的差值,用一个变量(maxRandom)来接收。在定义一个变量(serviceTime)来接收一个最大的随机值。通过把差值做为参数做为随机数的范围nextInt(maxRandom)+1(随机有可能为0,所以加1就从1到maxRandom)在加上最小的时间Constants.MIN_SERVICE_TIME(该类会在下面见到)。
private void commonService(){
String windowName = "第" + number + "号" + type + "窗口";
System.out.println(windowName + "开始获取普通任务!");
Integer serviceNumber = NumberMachine.getInstance().getCommonManager().fetchNumber();
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 {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
MainClass:该类是入口类(也可以理解为产生客户类)。该类主要实现功能是:创建不同的服务窗口类,并实例化,还要启动服务窗口线程。
for(int i=1;i<5;i++){//创建了4个普通客户
ServiceWindow window = new ServiceWindow();
window.setNumber(i);
window.start();
}
//创建了1个快速窗口
ServiceWindow expressWindow = new ServiceWindow();
expressWindow.setType(CustomerType.EXPRESS);//传入客户的类型
expressWindow.start();
//创建了1个VIP窗口
ServiceWindow vipWindow = new ServiceWindow();
vipWindow.setType(CustomerType.VIP);//传入客户的类型
vipWindow.start();
该类也用到了线程池(也叫定时器,这里的线程池跟ServiceWindow里的线程池是有差别的,大家注意一下就明白了),基本的实现功能也是一样,都是实现客户拿号的功能。我也同样拿普通客户的线程池来说:每一个客户就表示一个线程,所以在newScheduledThreadPool(1)参数里面就参入1。scheduleAtFixedRate()该方法有4个参数,每个参数分别表示:传入一个Runnable线程、过多长时间再来一个客户、以后每隔多长时间在来一个客户、时间的单位是秒。
//普通客户拿号
Executors.newScheduledThreadPool(1).scheduleAtFixedRate(
new Runnable(){
public void run(){
Integer serviceNumber = NumberMachine.getInstance().getCommonManager().generateNewNumber();
System.out.println("第" + serviceNumber + "号普通客户正在等待服务!");
}
},
0,//过多长时间再来一个客户
Constants.COMMON_CUSTOMER_INTERVAL_TIME, //以后每隔多长时间在来一个客户
TimeUnit.SECONDS);//时间的单位是秒
Constants:定义三个常量分别表示最大的时间、最小的时间、多少时间产生一个客户:MAX_SERVICE_TIME、MIN_SERVICE_TIME、COMMON_CUSTOMER_INTERVAL_TIME。这里定义的时间分别是:10000、1000、1
- 学习银行业务调度系统一些理解
- 银行业务调度系统学习
- 银行业务调度系统学习
- 银行业务调度系统学习
- 银行业务调度系统学习
- 银行业务调度系统学习
- 银行业务调度系统学习
- 银行业务调度系统学习
- 银行业务调度系统视频学习
- 银行业务调度系统学习总结
- 银行业务调度系统 学习笔记
- 银行业务调度系统的学习
- 银行业务调度系统学习总结
- 银行业务调度系统学习笔记
- 银行业务调度系统学习总结
- 银行业务调度系统的学习
- 银行业务调度系统学习总结
- 对银行业务调度系统的理解
- com入门小例子!理解com中的QueryInterface
- android 导航软件
- jrebeleclipse/tomcat 使用方法
- java 处理 Linux时间
- 为什么开发人员工作10多年了还会迷茫?
- 学习银行业务调度系统一些理解
- 同时支持google地图和卫星图
- SQLServer数据库总结
- JRebel3.0发布——热插拔重装上阵
- 谈java中装饰者模式与继承的区别
- 在SQL Server 2008 存储过程中拼接字符串时,若存在varchar和数值型则varchar自动转化为数值型
- ios弹出窗口自动渐渐隐藏
- 程序员到底怎么了?
- fastJSON例子2